Is it possible to view Mutant states from a Crash Dump File?


  1. Posts : 25
    Windows 7 Ultimate x64
       #1

    Is it possible to view Mutant states from a Crash Dump File?


    Hi. I have a simple application that holds a Mutex (Mutant) object. If I attach to the process with WinDbg and enter:

    Code:
     0:001> !handle 0 f Mutant
    Handle 7f4
      Type             Mutant
      Attributes       0
      GrantedAccess    0x1f0001:
             Delete,ReadControl,WriteDac,WriteOwner,Synch
             QueryState
      HandleCount      2
      PointerCount     4
      Name             \BaseNamedObjects\PAUL_HANG_MUTEX
      Object Specific Information
        Mutex is Owned
    ..then I can see that my application does indeed own the Mutex. Great.

    Now then.. I would like to be able to do the same thing but my generating a crash dump file so that I can exame the mutex states at the time that I invoke the crash dump. I've tried creating a crashdump using PROCDUMP -ma test.exe.

    Admittedly, I am looking into a problem on a Windows XP machine, not a Windows 7 machine but I have yet to find a good crash dump analysis forum that isn't specific to one version of Windows.

    Can somebody please tell me if and how it is possible to view the "owned" states from a crash dump file?

    Thanks
      My Computer


  2. Posts : 1,314
    Windows 7 64-bit
       #2

    If you've managed to break into your code during a debugging session then you can dump the state of the application right there in Windbg using the .dump command. Follow the instructions in the Help manual for Windbg on the appropriate parameters.

    As for viewings the actual states of an object like a mutex, you'll most likely need to have access to a kernel debugging session or generate a kernel or full dump during the break-in. This article I've found is pretty much on the money on the two common approaches you can make to find this answer (the kernel debugging method, once you successfully initiate it, is the easiest and most precise IMO). It's dated, but it's still very relevant.

    Btw, concerning having a good forum to go too for questions like this, I'd recommend Stack Overflow. There is a section there on debugging applications with some knowledgeable people to assist. In addition is OSR Online's forum/mailing list. It's more catered to driver writers, but you may be able to get some assistance there.
      My Computer


  3. Posts : 25
    Windows 7 Ultimate x64
    Thread Starter
       #3

    Thanks, I'll have a look at those 2 links you gave me. Unfortunately I'm not in a position to run the kernel mode debugger on the problematic sites. WinDbg does give me the information I require when I manually attach to the process. The problem for me is that I need to get the crash dump information passively. I've written a program which will detect a lack of activity in one of my debug logs (which indicates the program has frozen for a period of time). When this happens, my application attaches itself as a debugger and writes a minidump for me. PROCDUMP -h cannot be used as I'm trying to figure out which of my mutex objects are in a waiting state when the problem occurs - its not a Windows hang as such.

    However, attaching WinDbg manually and running .dump /f /ma m:\temp\paul.dmp, I closed WinDbg, loaded the paul.dmp file and I was able to see the states of the mutex objects! Aha! So.. I must be able to do what I require - probably just a matter of getting the correct MiniDumpWriteDump() API parameter combinations.
      My Computer


  4. Posts : 1,314
    Windows 7 64-bit
       #4

    Don't forget that Windbg is only an enhanced frontend of kd/cdb. You may not be able to run scripts to call Windbg, but you can to kd. Use this to your advantage when you wish to automate certain functions that you'd do in Windbg, like the .dump command.
      My Computer


  5. Posts : 25
    Windows 7 Ultimate x64
    Thread Starter
       #5

    Vir Gnarus said:
    Don't forget that Windbg is only an enhanced frontend of kd/cdb. You may not be able to run scripts to call Windbg, but you can to kd. Use this to your advantage when you wish to automate certain functions that you'd do in Windbg, like the .dump command.
    Actually that sounds like a much simpler solution.. only problem is that I'll have to install CDB etc.

    cdb -pn test.exe -c ".dump /f /ma test.dmp"

    The above command will almost do what I require.. How would I go about adding multiple commands? What I require is the means to attach, create the dump file, detach, and quit.

    Aha.. like this:

    cdb -pn test.exe -c ".dump /f /ma test.dmp;.detach;q"
      My Computer


  6. Posts : 25
    Windows 7 Ultimate x64
    Thread Starter
       #6

    Hmm. I don't know what I'm not doing but I simply cannot get my own debugger to save the "Mutex Owned" or "Mutex Free" info. CDB works fine as I indicated above but I cannot get my own crash dump function to include the information.

    Below is my function - I had to comment out some of the MiniDumpWith options as it would not write the crash dump file at all unless I commented them out.

    Anybody know why CDB can save the info when I use /ma and yet my own code cannot?

    Code:
    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            
    //|    MiniDumpWithFullMemoryInfo             
    //|    MiniDumpWithThreadInfo                 
    //|    MiniDumpWithCodeSegs                   
    //|    MiniDumpWithoutManagedState           
        ;
    
        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 );
        } 
    }
      My Computer


  7. Posts : 1,314
    Windows 7 64-bit
       #7

    I'm afraid I can't help ya there. I'm not a programmer, I just do forensic troubleshooting. Stack Overflow, Sysinternals forum, OSR online, etc., should be able to assist you in the endeavor. Since you're writing your own debugger, OSR Online forums would be a very good bet. Answers will not come quick, but they're from solid professionals.
      My Computer


  8. Posts : 25
    Windows 7 Ultimate x64
    Thread Starter
       #8

    I posted a question on MSDN and somebody kindly provided me the answer to my problem. Here's the link Why does MiniDumpWriteDump fail? to the discussion, and the working code snippet I've copied below.

    Thanks for all your help - I hope this thread proves useful to somebody else in the same boat as I.

    Code:
    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 );
      My Computer


  9. Posts : 1,314
    Windows 7 64-bit
       #9

    Jawsome. A lot of it seemed to matter on just figuring the proper calls to get the right context. I'm personally confused why they wouldn't have any MSDN articles on the CONTEXT structure. Maybe it's one of those things that's tucked within the header files in the WDK. I've often found that was the case when trying to find info on certain structures. What's not in the MSDN usually resides in the WDK header files.
      My Computer


 

  Related Discussions
Our Sites
Site Links
About Us
Windows 7 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 7" and related materials are trademarks of Microsoft Corp.

© Designer Media Ltd
All times are GMT -5. The time now is 02:01.
Find Us