2012-03-23 5 views
2

J'ai créé ma propre application de débogage. Il attache à un processus et crée un fichier de vidage sur incident. Cela fonctionne la plupart du temps. Le problème que j'ai, c'est que cela ne fonctionnera pas lorsque l'application en cours de débogage attend un objet mutex (et c'est le problème même que je veux déboguer).Pourquoi MiniDumpWriteDump échoue?

En outre, j'ai créé une application test.exe simple qui boucle juste et appelle Sleep (100) mais mon débogueur échoue quand il appelle MiniDumpWriteDump sur cette application à chaque fois.

Qu'est-ce que je fais mal?

Le code d'erreur je suis retourné à partir du code ci-dessous est 2147942699 (0x8007012b)

void WriteCrashDump(EXCEPTION_DEBUG_INFO *pExceptionInfo) 
{ 
    CONTEXT c; 

    memset(&c, 0, sizeof(c)); 

    GetThreadContext(hThread, &c); 

    EXCEPTION_POINTERS ep; 

    memset(&ep, 0, sizeof(ep)); 

    ep.ContextRecord = &c; 
    ep.ExceptionRecord = &pExceptionInfo->ExceptionRecord; 

    MINIDUMP_EXCEPTION_INFORMATION minidump_exception; 

    memset(&minidump_exception, 0, sizeof(minidump_exception)); 

    minidump_exception .ThreadId   = dwThreadId; 
    minidump_exception.ExceptionPointers = &ep; 
    minidump_exception.ClientPointers = true; 

    char txDumpPath[ MAX_PATH + 1 ]; 

    sprintf(txDumpPath, "%s.dmp", txProcess); 

    HANDLE hFile = CreateFile(txDumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

    if(hFile) 
    { 
    BOOL fSuccess; 


    SetLastError(0L); 

    int nDumpOptions = 

    MiniDumpNormal 
| MiniDumpWithDataSegs     
| MiniDumpWithFullMemory     
| MiniDumpWithHandleData     
| MiniDumpFilterMemory     
| MiniDumpScanMemory      
| MiniDumpWithUnloadedModules   
| MiniDumpWithIndirectlyReferencedMemory 
| MiniDumpFilterModulePaths    
| MiniDumpWithProcessThreadData   
| MiniDumpWithPrivateReadWriteMemory  
| MiniDumpWithoutOptionalData   
    ; 

    fSuccess = MiniDumpWriteDump(hProcess, 
            dwProcessId, 
            hFile, 
            (MINIDUMP_TYPE) nDumpOptions, 
            &minidump_exception, 
            NULL, 
            NULL); 

    DWORD dwErr = GetLastError(); 

    if(! fSuccess) 
      printf("MiniDumpWriteDump -FAILED (LastError:%u)\n", dwErr); 

     CloseHandle(hFile); 
    } 
} 

J'ai aussi essayé d'augmenter les privilèges avec le code suivant que j'emprunté à quelqu'un d'autre qui semblait avoir un effet semblable problème:

BOOL SetDumpPrivileges() 
{ 
    BOOL  fSuccess = FALSE; 
    HANDLE  TokenHandle = NULL; 
    TOKEN_PRIVILEGES TokenPrivileges; 

    if (!OpenProcessToken(GetCurrentProcess(), 
     TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
     &TokenHandle)) 
    { 
     printf("Could not get the process token"); 
     goto Cleanup; 
    } 

    TokenPrivileges.PrivilegeCount = 1; 

    if (!LookupPrivilegeValue(NULL, 
     SE_DEBUG_NAME, 
     &TokenPrivileges.Privileges[0].Luid)) 
    { 
     printf("Couldn't lookup SeDebugPrivilege name"); 
     goto Cleanup; 
    } 

    TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

    //Add privileges here. 
    if (!AdjustTokenPrivileges(TokenHandle, 
     FALSE, 
     &TokenPrivileges, 
     sizeof(TokenPrivileges), 
     NULL, 
     NULL)) 
    { 
     printf("Could not revoke the debug privilege"); 
     goto Cleanup; 
    } 

    fSuccess = TRUE; 

Cleanup: 

    if (TokenHandle) 
    { 
     CloseHandle(TokenHandle); 
    } 

    return fSuccess; 
} 

Répondre

2

I posté une question sur MSDN et quelqu'un m'a gentiment fourni la réponse à mon problème. Voici le link à la discussion, et l'extrait de code de travail que j'ai copié ci-dessous.

void WriteCrashDump(EXCEPTION_DEBUG_INFO *pExceptionInfo) 
{ 
    CONTEXT c; 

    memset(&c, 0, sizeof(c)); 

    HANDLE hThread; 
    c.ContextFlags = CONTEXT_FULL; 
    hThread = _OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadId); 

    GetThreadContext(hThread, &c); 

    EXCEPTION_POINTERS ep; 

    memset(&ep, 0, sizeof(ep)); 

    ep.ContextRecord = &c; 
    ep.ExceptionRecord = &pExceptionInfo->ExceptionRecord; 

    MINIDUMP_EXCEPTION_INFORMATION minidump_exception; 

    memset(&minidump_exception, 0, sizeof(minidump_exception)); 

    minidump_exception.ThreadId   = dwThreadId; 
    minidump_exception.ExceptionPointers = &ep; 
    minidump_exception.ExceptionPointers->ContextRecord = &c; 
    minidump_exception.ClientPointers = false; 

    char txDumpPath[ MAX_PATH + 1 ]; 

    time_t tNow = time(NULL); 
    struct tm *pTm = localtime(&tNow); 

    sprintf(txDumpPath, "%s.%02d%02d%04d_%02d%02d%02d.dmp", 
      txProcess, 
      pTm->tm_mday, 
      pTm->tm_mon, 
      pTm->tm_year, 
      pTm->tm_hour, 
      pTm->tm_min, 
      pTm->tm_sec); 

    HANDLE hFile = CreateFile(txDumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

    if(hFile != INVALID_HANDLE_VALUE) 
    { 
    BOOL fSuccess; 

    printf("hProcess : %d (0x%x)\n", hProcess, hProcess); 
    printf("dwProcessId: %u (0x%lx)\n", dwProcessId, dwProcessId); 
    printf("dwThreadId : %u (0x%lx)\n", dwThreadId, dwThreadId); 

    SetLastError(0L); 

    fSuccess = MiniDumpWriteDump(hProcess, 
            dwProcessId, 
            hFile, 
            MiniDumpNormal, 
            &minidump_exception, 
            NULL, 
            NULL); 

    DWORD dwErr = GetLastError(); 

    if(! fSuccess) 
    { 
     printf("MiniDumpWriteDump -FAILED (LastError:%u)\n", dwErr); 

     LPVOID lpMsgBuf; 

     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
        NULL, 
        dwErr, 
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 
        (LPTSTR) &lpMsgBuf, 
        0, 
        NULL); 

     // Display the string. 
     printf("%s\n", (LPCTSTR)lpMsgBuf); 

     // Free the buffer. 
     LocalFree(lpMsgBuf); 
    } 
    } 

    if(hThread) 
    CloseHandle(hThread); 
} 
+0

Salut, La chose ci-dessus ne fonctionne pas pour moi. La chose est que j'ai mon MiniDump écrit à partir d'un processus séparé. Est-ce que le vôtre est un gestionnaire de crash hors processus? ou en cours? Pouvez-vous clarifier? –

0

Est-ce problème, le même que l'autre question répondis-je avec ce texte?

Comprend-il pas les informations de mutex même avec le drapeau MiniDumpWithHandleData, aussi il est peut-être un échec parce que certains des drapeaux peuvent ne pas être compatibles avec la version de DebugHlp.dll vous appelez contre voir: here

+0

Bonjour à nouveau. Non, c'est un problème différent. Ma question précédente concernait l'écriture d'informations de poignée. Le problème que je décris ici est que MiniDumpWriteDump échoue à écrire quoi que ce soit du tout pour la plupart traitées. J'ai une petite application de test et il refuse de créer un vidage de n'importe quel type (crée un fichier de 0 octets de taille). Si j'attache l'application de débogage à l'une de nos plus grandes applications, elle écrira un vidage. – SparkyNZ