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