IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

RaiseExceptionProc / RaiseExceptObjProc jamais appelé sur exception ?!


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Points : 61
    Points
    61
    Par défaut RaiseExceptionProc / RaiseExceptObjProc jamais appelé sur exception ?!
    Bonjour,


    Voici mon problème :

    J'ai intégré à notre application un système permettant de récupérer la pile d'appels lorsqu'une exception a lieu. Ce système s'appuie que la lib "FastMM4" et sur la redéfinition du pointeur "System.RaiseExceptionProc".

    Cela fonctionne généralement très bien sauf dans certains cas ou alors qu'une exception a lieu (par exemple "violation d'accès") la fonction "System.RaiseExceptionProc" n'est pas appelée.

    J'ai essayé de comprendre en déboguant via l'IDE Delphi mais là problème ça marche normalement.

    En résumé :
    - Dans la majorité des cas "System.RaiseExceptionProc" est toujours appelé (en mode "debug" via Delphi et lors d'une lancement "standalone").
    - Dans certains cas (je n'arrive pas à savoir lesquels précisément) "System.RaiseExceptionProc" n'est appelé qu'en mode "debug" via Delphi.


    Dans mon cas de figure le problème se pose sur un gestionnaire "OnTimer", un code incorrect génère une violation d'acces qui déclenche une exception "EAccessViolation" sans appeler "System.RaiseExceptionProc" (sauf si en mode debug via l'IDE). Je précise que si je créé une exception "explicitement" avec un "raise Exception.Create(...);" dans ce même gestionnaire "OnTimer" alors "System.RaiseExceptionProc" est bien appelé.


    Avez-vous une idée de la cause de ce comportement ?

    Merci pour votre aide.

  2. #2
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    Si on en croit l'aide en ligne, RaiseExceptionProc n'est qu'un pointeur sur la fonction de l'API Windows qui sert à déclencher une exception.

    En modifiant ce pointeur, tu détournes toutes les fonctions qui passent par ce dernier pour déclencher une exception. Mais uniquement celles qui passent par lui.
    Ca semble fonctionner pour tous ce qui vient de la VCL. Mais les exceptions qui sont déclenchées par du code tiers, ou même directement par le système (par exemple, les Access Violation sont détectés directement par le processeur) ne doivent pas être interceptées de cette façon.

    Lorsque tu es en debug, Windows déclenche un événement au débogueur chaque fois qu'une exception se produit. De sorte que le débogueur voit toujours toutes les exceptions. Je ne serais pas étonné qu'ensuite il relaie l'exception à l'appli d'une façon qui passe par RaiseExceptionProc.

    Si tu veux être notifié du déclenchement de l'exception, est-ce qu'il ne faut pas plutôt utiliser RaiseExceptObjProc ?

    Personnellement, je me contente de JclDebug dans la Jcl. Il me semble qu'ils utilisent une autre approche qui consiste à injecter la fonction Windows.
    Quoi qu'il en soit, JclDebug fait exactement ce que tu veux : Intercepter les exceptions qui déclenche en capturant la pile d'appel. Si tu disposes des infos de debogage, tu peux également décoder les adresses et connaitre la position correspondante dans les sources.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Points : 61
    Points
    61
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    Si on en croit l'aide en ligne, RaiseExceptionProc n'est qu'un pointeur sur la fonction de l'API Windows qui sert à déclencher une exception.

    En modifiant ce pointeur, tu détournes toutes les fonctions qui passent par ce dernier pour déclencher une exception. Mais uniquement celles qui passent par lui.
    Ca semble fonctionner pour tous ce qui vient de la VCL. Mais les exceptions qui sont déclenchées par du code tiers, ou même directement par le système (par exemple, les Access Violation sont détectés directement par le processeur) ne doivent pas être interceptées de cette façon.

    Lorsque tu es en debug, Windows déclenche un événement au débogueur chaque fois qu'une exception se produit. De sorte que le débogueur voit toujours toutes les exceptions. Je ne serais pas étonné qu'ensuite il relaie l'exception à l'appli d'une façon qui passe par RaiseExceptionProc.

    Si tu veux être notifié du déclenchement de l'exception, est-ce qu'il ne faut pas plutôt utiliser RaiseExceptObjProc ?

    Personnellement, je me contente de JclDebug dans la Jcl. Il me semble qu'ils utilisent une autre approche qui consiste à injecter la fonction Windows.
    Quoi qu'il en soit, JclDebug fait exactement ce que tu veux : Intercepter les exceptions qui déclenche en capturant la pile d'appel. Si tu disposes des infos de debogage, tu peux également décoder les adresses et connaitre la position correspondante dans les sources.

    Merci pour ta réponse, et excuses-moi de te répondre aussi tardivement.

    J'ai essayé également de surcharger "RaiseExceptObjProc" mais là encore la procédure n'est jamais appelé. Je pensais juste que "RaiseExceptProc" permettait d'intercepter tout type d'exception, il y a d'ailleurs un des arguments de son prototype qui détermine le type d'exception concerné... Il va donc falloir que je me rallie à ton explication, et donc me résigner au fait que je n'ai pas de moyen de récupérer la pile d'appels sur certaines exceptions bien particulières... (le cas reste heureusement rare). Je n'ai pas l'intention de modifier tout l'implémentation actuelle car cela prendrais trop de temps ;-).

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 149
    Points : 61
    Points
    61
    Par défaut
    Citation Envoyé par ZZZzzz2 Voir le message
    Merci pour ta réponse, et excuses-moi de te répondre aussi tardivement.

    J'ai essayé également de surcharger "RaiseExceptObjProc" mais là encore la procédure n'est jamais appelé. Je pensais juste que "RaiseExceptProc" permettait d'intercepter tout type d'exception, il y a d'ailleurs un des arguments de son prototype qui détermine le type d'exception concerné... Il va donc falloir que je me rallie à ton explication, et donc me résigner au fait que je n'ai pas de moyen de récupérer la pile d'appels sur certaines exceptions bien particulières... (le cas reste heureusement rare). Je n'ai pas l'intention de modifier tout l'implémentation actuelle car cela prendrais trop de temps ;-).
    Je me réponds à moi-même, bien plus tard car j'ai trouvé une solution qui consiste à utiliser l'API Windows "AddVectoredExceptionHandler". En effet celle-ci permet d'ajouter une gestionnaire d'exception au moment où celle-ci a lieu et fort heureusement ce gestionnaire est appelé pour les exceptions de type "violation d'accès". Je récupère donc la pile d'appels dans ce gestionnaire...
    Il existe pas mal de liens sur Internet expliquant comment utiliser cette API avec Delphi donc je ne fournirai pas de détails ici je voulais juste indiquer qu'il existe une solution pour rattraper toutes les exceptions (perso j'ai combiné "RaiseExcepProc" avec "AddVectoredExceptionHandler" même si en définitif je pense que "AddVectoredExceptionHandler" est forcément appelé à partir du moment où on rentre dans "RaiseExcepProc"...)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JSF] Action methods jamais appelées
    Par mauvais_karma dans le forum JSF
    Réponses: 4
    Dernier message: 15/05/2007, 17h05
  2. [rmi]aide sur exception
    Par david06600 dans le forum API standards et tierces
    Réponses: 7
    Dernier message: 31/08/2006, 18h30
  3. [VBA-E] Procédure appelée sur clic des boutons de regroupement
    Par truman dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 02/05/2006, 12h34
  4. methode paint jamais appeller.
    Par Blo0d4x3 dans le forum 2D
    Réponses: 9
    Dernier message: 22/01/2006, 23h44
  5. [ Struts ] Erreur : l'action n'est jamais appelé
    Par romain3395 dans le forum Struts 1
    Réponses: 3
    Dernier message: 25/06/2004, 15h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo