1

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
dom_beau
  • 2,437
  • 3
  • 30
  • 59
  • @HansPassant See my **Edit 2**. You'll find a snippet of both apps and the stack trace when it breaks on exception. Note: VS 2015 Update 3 if it can help... – dom_beau Nov 13 '18 at 16:27
  • @HansPassant ...also note: created from scratch so `stdafx.h/.cpp`, `AssemblyInfo.cpp` etc are auto created by VS. I did not modify them... – dom_beau Nov 13 '18 at 16:29
  • @HansPassant dbghelp.dll: 6.1.7601.17514; both my apps were created on the same system/solution one after the other. The platform target is 8.1, the .NET is 4.6.1. – dom_beau Nov 13 '18 at 16:55
  • That is ancient Win7. Do you have any memory of using a recent SDK version of dbghelp.dll? Do you have a local copy of it? Double-check with the debugger's Debug > Windows > Modules window, it shows the actual dbghelp.dll that got loaded. I meant platform as in x64 vs Win32/x86. – Hans Passant Nov 13 '18 at 17:06
  • I don't have memory of that. In module window I see `c:\windows\system32\dbghelp.dll` symbols loaded with a path to my AppData\Local\Temp. The platform is x64 and the address is of course 64bit long... Actually I don't understand because the function returns TRUE as success even when I get the Access Violation Exception and the dump file is usable thereafter. And nothing bad occurs when I don't use the debugger (I'mean, stepping this API). – dom_beau Nov 13 '18 at 17:40
  • 2
    I don't think you have a real problem, just the debugger showing you more than you bargained for. DbgHelp knows how to take a lickin' and keep on tickin'. Root cause is surely a very old version of dbghelp.dll probing a very new version of the CLR. I have no good way to verify that. – Hans Passant Nov 13 '18 at 17:56
  • @HansPassant After working with the app, I think you're right. After all, nothing bad occurs... Anyway... Thanks for your help, I could learn a little more about the joy of DbgHelp.dll! – dom_beau Nov 13 '18 at 17:58

1 Answers1

0

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.

Menace
  • 1,061
  • 13
  • 15