Exceptions while using MiniDumpWriteDump() Win32 API while debuging

733 views Asked by At

I spawn a process "2" from a process "1" in C++/CLI. While both are running, process "1" kills process "2" (by design). My goal is to produce a mini dump of "2" just before killing it.

Here is my code:

// mpProcess started with System::Diagnostics::Process... etc.
System::IO::FileStream^ fs = gcnew System::IO::FileStream("MyPath.dmp");

MiniDumpWriteDump( mpProcess->Handle.ToPointer(), mpProcess->Id, fs->SafeFileHandle->DangerousGetHandle().ToPointer(), MINIDUMP_TYPE::MiniDumpNormal, nullptr, nullptr, nullptr);
fs->Close();

When I start process "1" from a command line, without attaching it to the debugger, it runs normally, starts process "2" then dumps it then kills it.

When I start process "1" in the debugger, I get 2-3 AccessViolationException when I step over the call to MiniDumpWriteDump, but if I click onto "Continue" everything goes fine and the dump file is produced.

What is going on? Is there something wrong in my design? Notice that it is the first time I use this API, I didn't even know I could dump such a file 24 hours ago ;-) ! I will be grateful for your kind help to improve my skills with dump files.

EDIT 1 Added Exception information:

Here is the message I got:

Exception thrown at 0x000007FED860FD31 (mscordacwks.dll) in MYProg.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

If there is a handler for this exception, the program may be safely continued.

EDIT 2 Added a snippet and a stack trace

Process 1: The "killer"

// Process1.cpp : main project file.

#include "stdafx.h"

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <dbghelp.h>

using namespace System;

int main(array<System::String ^> ^args)
{
     Console::WriteLine(L"Hello, I'm Process1! I'll \"minidump\" Process2 then kill it!");

    System::Diagnostics::Process^ p = gcnew System::Diagnostics::Process();

    p->StartInfo->FileName = "Process2.exe";
    p->Start();

    System::Threading::Thread::Sleep( 3000 );

    System::IO::FileStream^ fs = gcnew System::IO::FileStream( "minidump.dmp", System::IO::FileMode::Create );

    MiniDumpWriteDump( p->Handle.ToPointer(), p->Id, fs->SafeFileHandle->DangerousGetHandle().ToPointer(), MINIDUMP_TYPE::MiniDumpNormal, nullptr, nullptr, nullptr );

    fs->Close();

    p->Kill();

    return 0;
}

Process 2: the "dumped"

// Process2.cpp : main project file.

#include "stdafx.h"

using namespace System;

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Hello, I'm Process2! I'm waiting to be killed by Process1!");

    // Do nothing, wait to be killed
    while ( true )
    {
        System::Threading::Thread::Sleep( 1000 );
    }

    return 0;
}

Stack trace when I break it from within the (AccessViolation)Exception dialog:

mscordacwks.dll!000007fed860fd31()  Unknown
mscordacwks.dll!000007fed861028c()  Unknown
mscordacwks.dll!000007fed8610fd2()  Unknown
mscordacwks.dll!000007fed861165f()  Unknown
mscordacwks.dll!000007fed861176e()  Unknown
dbghelp.dll!GenGetAuxMemory(struct _MINIDUMP_STATE *,struct _INTERNAL_PROCESS *)    Unknown
dbghelp.dll!GenGetProcessInfo(struct _MINIDUMP_STATE *,struct _INTERNAL_PROCESS * *)    Unknown
dbghelp.dll!MiniDumpProvideDump()   Unknown
dbghelp.dll!MiniDumpWriteDump() Unknown
[Managed to Native Transition]  
[CURSOR]>>> Process1.exe!main(array<System::String^>^ args=array<System::String^>(0)) Line 24   C++
Process1.exe!mainCRTStartupStrArray(array<System::String^>^ arguments=array<System::String^>(0)) Line 249   C++
[Native to Managed Transition]  
mscoreei.dll!000007feee467a6d() Unknown
mscoree.dll!_CorExeMain_Exported()  Unknown
kernel32.dll!BaseThreadInitThunk()  Unknown
ntdll.dll!RtlUserThreadStart()  Unknown
1

There are 1 answers

0
Menace On

Like Hans Passant mentioned in the comments above, This seems to be an internal / caught exception. The MiniDumpWriteDump does something that causes an exception and catches its internal exception and continue. I don't really know why it would do this. You can just ignore it and continue. It seems harmless.

I've run into similar problems calling other (opaque) system API calls. The call itself internally catches its own exceptions. The debugger doesnt know if they are going to be caught or not and breaks on them.

They should not show up in release mode.