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

SparkyNZ

New member
Local time
5:21 PM
Messages
25
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 My Computer

At a glance

Windows 7 Ultimate x64
OS
Windows 7 Ultimate x64
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 My Computer

At a glance

Windows 7 64-bit
OS
Windows 7 64-bit
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 My Computer

At a glance

Windows 7 Ultimate x64
OS
Windows 7 Ultimate x64
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 My Computer

At a glance

Windows 7 64-bit
OS
Windows 7 64-bit
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 My Computer

At a glance

Windows 7 Ultimate x64
OS
Windows 7 Ultimate x64
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 My Computer

At a glance

Windows 7 Ultimate x64
OS
Windows 7 Ultimate x64
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 My Computer

At a glance

Windows 7 64-bit
OS
Windows 7 64-bit
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 My Computer

At a glance

Windows 7 Ultimate x64
OS
Windows 7 Ultimate x64
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 My Computer

At a glance

Windows 7 64-bit
OS
Windows 7 64-bit
Back
Top