0

I wish to debug application hang via collected crash dump from customer site as I cannot install visual studio and debugger on customer site machine. Full memory dump would be my first choice as debugging hang via full memory dump is informative and effective way. Nonetheless, as my application getting more complex from time to time, the RAM usage of the exe increase to almost 15GB (mostly heap memory image buffer), which take a huge toll on my collected crash dump. Thus, I am exploring a way to minimize the crash dump file while maintaining only specific useful heap memory region via MiniDumpWriteDump API options in DbgHelp library. However, I stuck when I try a way to append specific memory region via memory callback.

I had tried to refer to http://www.nynaeve.net/?p=126 to implement memory callback and https://www.debuginfo.com/articles/effminidumps.html#minidumptypes to choose my desired minidump types flag to minimize the dump size. So my current strategy would be minimize the size via flags below instead of using full memory dump flag

...
MINIDUMP_TYPE dwFlags = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory 
| MiniDumpScanMemory                                           
| MiniDumpWithHandleData                                        
| MiniDumpWithUnloadedModules                                   
| MiniDumpWithProcessThreadData
| MiniDumpWithFullMemoryInfo                                
| MiniDumpWithThreadInfo                                
| MiniDumpWithCodeSegs                                  
| MiniDumpWithDataSegs
);

MINIDUMP_CALLBACK_INFORMATION mci;
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MyMiniDumpCallback;
mci.CallbackParam   = pErrorLog;

BOOL rv = MiniDumpWriteDump(processHandle, dwProcessID, hFile, dwFlags, NULL, NULL, &mci); 
...

then using memory callback to append heap memory region

BOOL CALLBACK MyMiniDumpCallback(
    PVOID                            pParam, 
    const PMINIDUMP_CALLBACK_INPUT   pInput, 
    PMINIDUMP_CALLBACK_OUTPUT        pOutput 
) 
{
...
case MemoryCallback: 
{
     if(vctMemoryBlock.size() > 0)
     {
       pOutput->MemoryBase = vctMemoryBlock.back().uBase;
       pOutput->MemorySize = vctMemoryBlock.back().uSize;

      // logger function here... 

       vctMemoryBlock.pop_back();

       bRet = TRUE;
     }
     else
     {
       bRet = FALSE; 
     }

     //bRet = TRUE;
}
break; 

...
}

However, when I generate the crash dump and open it using visual studio 2015 then debug with native symbol, it stated heap memory not present and I can't get the detail of heap memory variable at that specific memory region.

I am not sure what I had done wrong, whether is the way I collect my heap memory address, or the way I implement crash dump generation above that causing issue.

Hopefully there is some master here which can guide me through...

Findings:

Custom dump with memory appended are larger than the one without memory appended dump size comparison

Full Memory Dump showing heap variable... Full Memory Dump Show Heap Variable

Custom Dump with memory appended unable to show heap variable Custom dump unable to show heap variable

Andrioux
  • 11
  • 4
  • The code you've shown always executes the last `bRet = TRUE;` making the `else` meaningless. Is the dump larger after adding the callback? Are you certain it is even called? – Retired Ninja Jul 25 '23 at 02:55
  • @RetiredNinja, thanks for pointing out, I have then modified the source code and test again. The dump indeed larger after adding the callback. I am certain it is called as I had put a logger in the callback ( i just removed from above for better visualization). However, I still can't get any heap variable info, I hereby attached my findings in above post – Andrioux Jul 25 '23 at 08:06
  • From you image we can see that s_theSingletonObj is a nullptr. I'm guessing that you added the memory that the s_theSingletonObj pointed to? Then what you forgot to do is add the memory that stores the global variable of the pointer to that memory... (i.e. &s_theSingletonObj for the pointer size. Most likely you also want to include the memory for what s_theSingletonObj instances point to as well. I think what you will find you will need is a "list" of areas you need to include in the dump to be useable. – Shane Powell Jul 25 '23 at 10:20
  • Also if you already "know" address you added to the dump file, you should be able to just point to it directly as a VS watch variable. e.g. (CSingletonObj*)0x0106f7d040 – Shane Powell Jul 25 '23 at 10:23
  • @ShanePowell, really thanks for your useful insights! I am able to get the dump memory info by just inputing (CSingletonObj*)0x0106f7d040 in my watch! May I know where can we refer to formulate such useful expression in watch window? – Andrioux Aug 01 '23 at 02:51
  • C++ or C# expressions depending on what you are debuging: https://learn.microsoft.com/en-us/visualstudio/debugger/expressions-in-the-debugger?view=vs-2022 – Shane Powell Aug 01 '23 at 05:02
  • Also the pseudovariables are useful as well like $err,hr https://learn.microsoft.com/en-us/visualstudio/debugger/pseudovariables?view=vs-2022 – Shane Powell Aug 01 '23 at 05:03

0 Answers0