2017-04-03 4 views
1

Supposons qu'un site distant rencontre une erreur rare mais ne plante pas l'application. Je voudrais quand même créer un mini fichier de vidage quand cela arrive, j'ai donc quelques informations à travailler, principalement la pile d'appels.Est-il possible de créer un fichier mini-dump par programmation sans crash?

pseudo-code est le suivant:

try 
{ 
    doStuff(); 
} 
catch(_com_error &e) 
{ 
    make_minidump(); // is this possible? 

    dump_com_error(e); 
    return FALSE; 
} 

Tous les exemples que je vois exige que je vais devoir faire l'application à planter (à des fins de démonstration au moins) pour produire le fichier de vidage mais je ne veux pas fais ça. Est-il possible de créer un fichier de vidage comme ça? Je sais que je peux aller au gestionnaire de tâches et créer un fichier de vidage d'un processus en cours d'exécution et de même que je peux utiliser ProcessExplorer pour atteindre le même, donc il semble que ce devrait être possible.

En même temps dans tous les exemples que je vois, le fichier de vidage est généré seulement quand les contrôles viennent à SetUnhandledExceptionFilter qui est appelée quand une application tombe en panne! En dernier recours, la seule façon d'obtenir un fichier de vidage est de planter délibérément l'application avec quelque chose comme ci-dessous: Cela produira-t-il quelque chose d'utile au-delà du crash? parce que je sais ce qui a causé l'accident dans ce cas.

LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) 
{ 
    make_minidump(e); 
    return EXCEPTION_CONTINUE_SEARCH; 
} 

int main() 
{ 
    SetUnhandledExceptionFilter(unhandled_handler); 

    return *(int*)0; 
} 
+3

https: // msdn. microsoft.com/fr-fr/library/windows/desktop/ms680360(v=vs.85).aspx –

+0

Possible duplicate (non marqué comme il est daté 2009) http://stackoverflow.com/questions/1547211/how-to -create-minidump-for-my-process-when-it-crash –

Répondre

2

Oui, bien sûr. Un gestionnaire de tâches similaire à Windows peut créer un vidage sur incident d'une application en cours d'exécution/suspension sans exception, vous pouvez utiliser MiniDumpWriteDump() pour créer un vidage sur incident. Il suffit de passer NULL pour ExceptionParam.

est ici un code qui pourrait aider:

typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, 
     MINIDUMP_TYPE DumpType, 
     CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 
     CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, 
     CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam 
             ); 

const wchar_t * DBGHELP = L"DbgHelp.dll"; 

bool Dump(const std::wstring & dumpFile) 
{ 
    bool success = false; 
    DllLoader loader; 

    // Load dbghelp.dll. Try first to find it in the application directory. 
    loader.Load(::GetModuleHandle(NULL), DBGHELP); 
    if (!loader.IsLoaded()) 
    { 
     loader.Load(DBGHELP); 
    } 

    if (loader.IsLoaded()) 
    { 
     MINIDUMPWRITEDUMP pDump = MINIDUMPWRITEDUMP(loader.GetProcAddress("MiniDumpWriteDump")); 

     if (pDump) 
     { 
      // Create dump file 
      HANDLE fileHandle = ::CreateFileW(dumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, 
               FILE_ATTRIBUTE_NORMAL, nullptr); 

      if (fileHandle != INVALID_HANDLE_VALUE) 
      { 
       BOOL bOK = pDump(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, MiniDumpWithFullMemory, nullptr, nullptr, nullptr); 
       if (bOK) 
       { 
        success = true; 
       } 

       ::CloseHandle(fileHandle); 
      } 
     } 
    } 

    return success; 
} 

En raison de l'optimisation, je ne vois pas la pile correcte dans k, mais dds ebp le montrer:

0029f8d0 01302029 GetCrashWithDLL!MethodB+0x99 [f:\...\getcrashwithdll.cpp @ 12] 
[...] 
0029f914 0130209c GetCrashWithDLL!wmain+0x3c [f:\...\getcrashwithdll.cpp @ 31] 
[...] 
0029f920 01302cff GetCrashWithDLL!__tmainCRTStartup+0xfd [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c @ 623] 
+0

J'ai essayé [ceci] (http://ntcoder.com/bab/2014/10/14/how-to-create-pleine-mémoire-dumps-using-minidumpwritedump /) dans le temps et créé le fichier de vidage, mais le pointeur EBP de base est 0x00000 et il ne se brise pas dans mon fonction. Je regarde votre code, mais je ne sais pas ce que DllLoader est? Merci. – zar

+0

DllLoader est juste un wrapper autour de ':: LoadLibrary()'. Rien de spécial. –

+0

@zar: ce code est censé créer un vidage sur incident en dehors d'un processus. Vous devez avoir de la chance d'avoir votre fonction sur la pile d'appels tant qu'elle n'est pas très longue ou suspendue. –