8

When using the MiniDumpWriteDump function to create a core dump of a process on Windows, it is recommended (e.g. here, and here) that the MiniDumpWriteDump is run from another "watchdog" process because it may well not work when called from within the same process.

At the moment, our application is calling it in-process on an unhandled exception (we do it from a watchdog thread). Since we sometimes have problems with it not working, we'd like to move it to a separate process.

Now, signalling the other process to start writing the dump is trivial (just use an event, semaphore, you name it) but how do I pass the LPEXCEPTION_POINTERS info I get for the callback function I register with SetUnhandledExceptionFilter to the other process so that it can be passed to MiniDumpWriteDumps ExceptionParam argument??

Community
  • 1
  • 1
Martin Ba
  • 37,187
  • 33
  • 183
  • 337

2 Answers2

7

You also need the MINIDUMP_EXCEPTION_INFORMATION.ThreadId value. The simplest way, and the way I made it work, is to use a memory-mapped file to transfer both the ThreadId and the ExceptionPointers. And a named event to wake up the watchdog. It doesn't matter that the pointer is not valid in the context of the watchdog process.

Use CreateFileMapping + MapViewOfFile in the watched process as part of its initialization, OpenFileMapping + MapViewOfFile in the watchdog. Your SetUnhandledExceptionFilter should then only call GetCurrentThreadId() and copy the tid and the pExcept to the memory mapped file view, call SetEvent() to wake up the watchdog and block forever until the watchdog terminates it.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • *"It doesn't matter that the pointer is not valid in the context of the watchdog process."* ... ah! This info is important. Thanks for that. I guess I'll just have to implement and see if I get it to work. – Martin Ba Nov 28 '12 at 09:12
  • @Martin Ba : Any update on this ? How to proceed further ? I also have a similar requirement and am stuck in the middle. How did you pass the exception data? through pipes or file mapping ? – Anantha Subramaniam Apr 19 '13 at 04:31
  • @ananth: I used a file mapping: `CreateFileMapping(INVALID_HANDLE_VALUE/*means shared memory backed by page file*/, NULL, PAGE_READWRITE, ...` (despite the name `Create...`, you can use this fn to create and to open the file mapping.) – Martin Ba Apr 19 '13 at 07:04
  • @Martin Ba : I am using the same but i face trouble in passing the exception pointers and information . If you could help with that part of code it would be great . – Anantha Subramaniam Apr 19 '13 at 07:57
  • @MartinBa : This is the specific problem http://stackoverflow.com/questions/16147753/trouble-passing-exception-pointers-using-filemapping – Anantha Subramaniam Apr 22 '13 at 13:02
  • 1
    @MartinBa : To be more specific i too understood "It doesn't matter that the pointer is not valid in the context of the watchdog process." and passed the pointer as it is which results in failing to create minidump . the MINIDUMP_EXCEPTION_INFORMATION ( this is the one am sharing ) is 0 . – Anantha Subramaniam Apr 23 '13 at 09:25
0

While Hans answer is correct, I found that an easier way is to use WM_COPYDATA to transfer information from main process to minidump process. Register a class and a HWND_MESSAGE type window with some custom names in minidump process, then wait for WM_COPYDATA message in WndProc. Use FindWindow with same class name and window name in main process to obtain HWND to your minidump window. Use SendMessage with this handle to send WM_COPYDATA message with whenever struct you want to use. This will block your application until minidump process will receive and process it. Note that one of WM_COPYDATA parameters is a handle to window that sent it, but you will still need to use OpenProcess to get a proper process handle to use in MiniDumpWriteDump, so a "minimal" message to send is probably

  • process ID (to obtain process handle with OpenProcess)
  • thread ID (to initialize MINIDUMP_EXCEPTION_INFORMATION)
  • LPEXCEPTION_POINTERS (to initialize MINIDUMP_EXCEPTION_INFORMATION)

This way you will get all the necessary data in minidump's WndProc to call MiniDumpWriteDump. Make sure to set ClientPointers field in MINIDUMP_EXCEPTION_INFORMATION to TRUE since we're debugging external process. Note that when running under debugger in MSVC the call to MiniDumpWriteDump might produce flurry of exceptions like trying to read invalid memory address - simply ignore this, it's normal (and you don't need to intercept any of those)

Once your minidump process finished writing the dump, it will return from WndProc and main process will return from SendMessage. Then you can either terminate your main app or do any other stuff in exception handler (e.g. we show a nice message box to user and close the app gracefully).

Sergei Ozerov
  • 460
  • 5
  • 12