c++ - tools - Création d'une exception de violation d'accès pour minidump à l'aide de SetUnhandledExceptionFilter()




windows script debugger (2)

Cependant, aucune information ne vient ici (c'est-à-dire que je ne reçois pas la pile d'appels)

.ecxr n'est pas censé imprimer une pile d'appel, c'est juste supposé placer le contexte à celui de l'enregistrement d'exception stocké - vous voudriez faire quelque chose comme k 10 pour l'imprimer réellement. Ou, puisque vous utilisez WinDBG, ouvrez la fenêtre callstack.

(Peut-être que vous faites déjà ceci, je ne suis pas sûr de votre description comment .ecxr échoue - il devrait imprimer quelque chose pour vous faire savoir ce qu'il est / n'est pas capable de faire ...)

Une autre chose à vérifier est que vous obtenez des pointeurs d'exception - le code générera une sauvegarde sans eux, mais vous obtiendrez une callstack funky de cette façon.

Vous avez mentionné dans un commentaire sur la réponse d'Alex avoir une certaine interférence d'une DLL remplaçant votre filtre avec la bibliothèque d'exécution ... C'est un problème commun. J'ai eu de la chance en utilisant la technique décrite par Oleg Starodumov :

Il y a une autre approche possible, et elle est beaucoup plus facile à mettre en œuvre que les deux précédentes. Après avoir enregistré notre propre filtre, nous pouvons patcher le début de la fonction SetUnhandledExceptionFilter afin qu'il ne puisse plus enregistrer les filtres.

Il fournit un exemple pratique de code à cette fin, ce qui m'a bien servi au fil des ans.

J'utilise le code suivant pour créer un fichier minidump chaque fois qu'une exception structurée est générée à partir de mon code:

void CreateMiniDump( EXCEPTION_POINTERS* pep ) 
{
  // Open the file 
typedef BOOL (*PDUMPFN)( 
  HANDLE hProcess, 
  DWORD ProcessId, 
  HANDLE hFile, 
  MINIDUMP_TYPE DumpType, 
  PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 
  PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, 
  PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);


    HANDLE hFile = CreateFile( _T("C:/temp/MiniDump.dmp"), GENERIC_READ | GENERIC_WRITE, 
    0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 

    HMODULE h = ::LoadLibrary(L"DbgHelp.dll");
    PDUMPFN pFn = (PDUMPFN)GetProcAddress(h, "MiniDumpWriteDump");

  if( ( hFile != NULL ) && ( hFile != INVALID_HANDLE_VALUE ) ) 
  {
    // Create the minidump 

    MINIDUMP_EXCEPTION_INFORMATION mdei; 

    mdei.ThreadId           = GetCurrentThreadId(); 
    mdei.ExceptionPointers  = pep; 
    mdei.ClientPointers     = TRUE; 

    MINIDUMP_TYPE mdt       = MiniDumpNormal; 

    BOOL rv = (*pFn)( GetCurrentProcess(), GetCurrentProcessId(), 
      hFile, mdt, (pep != 0) ? &mdei : 0, 0, 0 ); 



    // Close the file 

    CloseHandle( hFile ); 

  }

}

LONG WINAPI MyUnhandledExceptionFilter(
 struct _EXCEPTION_POINTERS *ExceptionInfo
)
 {
     CreateMiniDump(ExceptionInfo);
     return EXCEPTION_EXECUTE_HANDLER;
 }

Et je fais SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); à partir du point d'entrée principal de mon application (je ne le mets pas pour chaque thread si). Après cela pour tester ce code, j'ai fait ce qui suit pour générer une violation d'accès: int* p = 0; *p = 0; int* p = 0; *p = 0; Le fichier de vidage a été généré. Ensuite, j'ai utilisé windbg et ouvert le fichier de vidage et utilisé la commande .ecxr pour obtenir l'enregistrement d'exception. Cependant, aucune information ne vient ici (c'est-à-dire que je ne reçois pas la pile d'appels). Aussi, si j'utilise !analyze -v commande, il est capable d'afficher la ligne où le crash s'est produit. Est-ce que quelqu'un sait ce que je manque et comment résoudre ceci?

BTW, j'utilise VC7 compilateur avec / EHa (asynchronuos exception modèle) drapeau.


Votre code créant minidump est OK, le problème est le débogage post-mortem. Le débogueur doit avoir accès au code source du programme, aux fichiers .pdb (qui doivent être des fichiers pdb créés lors de la construction de cet exécutable) et aux symboles de débogage du système d'exploitation. Seulement ayant toutes ces informations, le débogueur peut montrer l'endroit d'exception dans le code source et la pile d'appel.

Le processus de débogage post-mortem à l'aide du débogueur Visual Studio est décrit en détails ici: http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx Pour WinDbg, utilisez le chemin de fichier Symbol, Source et Image pour fournir les mêmes informations pour le débogueur .





windbg