I'm trying to write a minidump from within the unhandled exception handler in a managed C# application (.NET Framework 2.0):
namespace MiniDumpTest {
class Program {
static void Main(string[] args) {
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Console.WriteLine("started");
try {
Console.WriteLine(MyFunc());
} finally {
Console.WriteLine("finished");
Console.ReadLine();
}
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
if (MiniDump.MakeDump(@"D:\Work\Visual Studio.NET\MiniDumpTest\MiniDumpTest\bin\Release\MyDump.dmp", MiniDumpType.WithFullMemory)) {
Console.WriteLine("MiniDump written");
} else {
Console.WriteLine("Failed to write MiniDump");
}
}
static int MyFunc() {
int i = 0;
++i;
if (i == 1) {
throw new ApplicationException("bla");
}
return i;
}
}
public static class MiniDump {
public static bool MakeDump(String dmpPath, MiniDumpType dmpType) {
MinidumpExceptionInfo mMei;
mMei.ThreadId = GetCurrentThreadId();
mMei.ExceptionPointers = Marshal.GetExceptionPointers();
mMei.ClientPointers = false;
using (FileStream stream = new FileStream(dmpPath, FileMode.Create)) {
Process process = Process.GetCurrentProcess();
IntPtr mem = Marshal.AllocHGlobal(Marshal.SizeOf(mMei));
Marshal.StructureToPtr(mMei, mem, false);
Boolean success = MiniDumpWriteDump(
process.Handle,
process.Id,
stream.SafeFileHandle.DangerousGetHandle(),
dmpType,
mMei.ClientPointers ? mem : IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
Marshal.FreeHGlobal(mem);
return success;
}
}
[DllImport("DbgHelp.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
private static extern Boolean MiniDumpWriteDump(
IntPtr hProcess,
Int32 processId,
IntPtr fileHandle,
MiniDumpType dumpType,
IntPtr excepInfo,
IntPtr userInfo,
IntPtr extInfo);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[StructLayout(LayoutKind.Sequential)]
struct MinidumpExceptionInfo {
public Int32 ThreadId;
public IntPtr ExceptionPointers;
public bool ClientPointers;
}
}
public enum MiniDumpType {
Normal = 0x00000000,
WithDataSegs = 0x00000001,
WithFullMemory = 0x00000002,
WithHandleData = 0x00000004,
FilterMemory = 0x00000008,
ScanMemory = 0x00000010,
WithUnloadedModules = 0x00000020,
WithIndirectlyReferencedMemory = 0x00000040,
FilterModulePaths = 0x00000080,
WithProcessThreadData = 0x00000100,
WithPrivateReadWriteMemory = 0x00000200,
WithoutOptionalData = 0x00000400,
WithFullMemoryInfo = 0x00000800,
WithThreadInfo = 0x00001000,
WithCodeSegs = 0x00002000,
WithoutAuxiliaryState = 0x00004000,
WithFullAuxiliaryState = 0x00008000
}
}
When analyzing the minidump in WinDbg the source line information is missing in the call stack even though the PDBs do match and all the paths (symbol, source, image) are set correctly.
I get the following output in WinDbg:
Microsoft (R) Windows Debugger Version 6.11.0001.404 X86
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [D:\Work\Visual Studio.NET\MiniDumpTest\MiniDumpTest\bin\Release\MyDump.dmp]
User Mini Dump File with Full Memory: Only application data is available
Symbol search path is: D:\Work\Visual Studio.NET\MiniDumpTest\MiniDumpTest\bin\Release;C:\WINDOWS\Symbols;symsrv*symsrv.dll*c:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is: D:\Work\Visual Studio.NET\MiniDumpTest\MiniDumpTest\bin\Release
Windows XP Version 2600 (Service Pack 2) MP (2 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Wed Sep 23 07:46:44.000 2009 (GMT+2)
System Uptime: 1 days 23:57:25.040
Process Uptime: not available
......................
eax=000006b8 ebx=0014b0e0 ecx=00df1ea8 edx=000006b4 esi=0012e5a0 edi=0012e990
eip=7c90e514 esp=0012db74 ebp=0012db84 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet:
7c90e514 c3 ret
0:000> .load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll
0:000>
0:000> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
*** WARNING: Unable to verify checksum for MiniDumpTest.exe
*** WARNING: Unable to verify checksum for mscorlib.ni.dll
*** WARNING: Unable to verify checksum for System.ni.dll
*************************************************************************
*** ***
*** ***
*** Your debugger is not using the correct symbols ***
*** ***
*** In order for this command to work properly, your symbol path ***
*** must point to .pdb files that have full type information. ***
*** ***
*** Certain .pdb files (such as the public OS symbols) do not ***
*** contain the required information. Contact the group that ***
*** provided you with these symbols if you need this command to ***
*** work. ***
*** ***
*** Type referenced: kernel32!pNlsUserInfo ***
*** ***
*************************************************************************
*************************************************************************
*** ***
*** ***
*** Your debugger is not using the correct symbols ***
*** ***
*** In order for this command to work properly, your symbol path ***
*** must point to .pdb files that have full type information. ***
*** ***
*** Certain .pdb files (such as the public OS symbols) do not ***
*** contain the required information. Contact the group that ***
*** provided you with these symbols if you need this command to ***
*** work. ***
*** ***
*** Type referenced: kernel32!pNlsUserInfo ***
*** ***
*************************************************************************
FAULTING_IP:
+152952f00a9df74
00000000 ?? ???
EXCEPTION_RECORD: 0012eff4 -- (.exr 0x12eff4)
ExceptionAddress: 7c812aab (kernel32!RaiseException+0x00000053)
ExceptionCode: e0434f4d (CLR exception)
ExceptionFlags: 00000001
NumberParameters: 1
Parameter[0]: 80131600
FAULTING_THREAD: 000017b0
DEFAULT_BUCKET_ID: CLR_EXCEPTION
PROCESS_NAME: MiniDumpTest.exe
ERROR_CODE: (NTSTATUS) 0x80000003 - {EXCEPTION} Breakpoint A breakpoint has been reached.
EXCEPTION_CODE: (HRESULT) 0x80000003 (2147483651) - One or more arguments are invalid
NTGLOBALFLAG: 0
APPLICATION_VERIFIER_FLAGS: 0
MANAGED_STACK:
(TransitionMU)
0012E5C4 00C502D0 MiniDumpTest!MiniDumpTest.MiniDump.MakeDump(System.String, MiniDumpTest.MiniDumpType)+0xf8
0012E610 00C50154 MiniDumpTest!MiniDumpTest.Program.CurrentDomain_UnhandledException(System.Object, System.UnhandledExceptionEventArgs)+0x14
(TransitionUM)
(TransitionMU)
0012F458 00C501C7 MiniDumpTest!MiniDumpTest.Program.MyFunc()+0x2f
0012F460 00C500CC MiniDumpTest!MiniDumpTest.Program.Main(System.String[])+0x5c
(TransitionUM)
EXCEPTION_OBJECT: !pe 12811c8
Not a valid exception object
MANAGED_OBJECT_NAME: System.AppDomain
CONTEXT: 0012f00c -- (.cxr 0x12f00c)
eax=0012f2dc ebx=e0434f4d ecx=00000000 edx=00000028 esi=0012f368 edi=0014b0e0
eip=7c812aab esp=0012f2d8 ebp=0012f32c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
kernel32!RaiseException+0x53:
7c812aab 5e pop esi
Resetting default scope
LAST_CONTROL_TRANSFER: from 7c90cffa to 7c90e514
STACK_TEXT:
0012f32c 79eda99c e0434f4d 00000001 00000001 kernel32!RaiseException+0x53
0012f38c 79fb48f8 01284d48 00000000 00000000 mscorwks!RaiseTheExceptionInternalOnly+0x2a8
0012f450 00c501c7 01284d48 00c500cc 0012f490 mscorwks!JIT_Throw+0xfc
WARNING: Frame IP not in any known module. Following frames may be wrong.
0012f480 79e71b4c 0012f4cc 00000000 0012f510 0xc501c7
0012f490 79e821f9 0012f560 00000000 0012f530 mscorwks!CallDescrWorker+0x33
0012f510 79e96571 0012f560 00000000 0012f530 mscorwks!CallDescrWorkerWithHandler+0xa3
0012f648 79e965a4 0091c038 0012f714 0012f6e0 mscorwks!MethodDesc::CallDescr+0x19c
0012f664 79e965c2 0091c038 0012f714 0012f6e0 mscorwks!MethodDesc::CallTargetWorker+0x1f
0012f67c 79eefac5 0012f6e0 eaf67315 00000000 mscorwks!MethodDescCallSite::CallWithValueTypes+0x1a
0012f7e0 79eef9e5 00913010 00000001 0012f81c mscorwks!ClassLoader::RunMain+0x223
0012fa48 79eeff35 00000000 eaf67bed 00000001 mscorwks!Assembly::ExecuteMainMethod+0xa6
0012ff18 79ef011f 00400000 00000000 eaf67b9d mscorwks!SystemDomain::ExecuteMainMethod+0x456
0012ff68 79ef004f 00400000 eaf67b45 3b2c446c mscorwks!ExecuteEXE+0x59
0012ffb0 79007c24 01ca3c11 79e70000 0012fff0 mscorwks!_CorExeMain+0x15c
0012ffc0 7c817027 3b2c446c 01ca3c11 7ffd6000 mscoree!_CorExeMain+0x2c
0012fff0 00000000 79007bf0 00000000 78746341 kernel32!BaseProcessStart+0x23
PRIMARY_PROBLEM_CLASS: CLR_EXCEPTION
BUGCHECK_STR: APPLICATION_FAULT_CLR_EXCEPTION
FOLLOWUP_IP:
mscorwks!RaiseTheExceptionInternalOnly+2a8
79eda99c c745fcfeffffff mov dword ptr [ebp-4],0FFFFFFFEh
SYMBOL_STACK_INDEX: 1
SYMBOL_NAME: mscorwks!RaiseTheExceptionInternalOnly+2a8
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: mscorwks
IMAGE_NAME: mscorwks.dll
DEBUG_FLR_IMAGE_TIMESTAMP: 492b82c1
STACK_COMMAND: ~~[0x000017B0]s ; kb ; .cxr 0x12f00c ; kb
FAILURE_BUCKET_ID: CLR_EXCEPTION_80000003_mscorwks.dll!RaiseTheExceptionInternalOnly
BUCKET_ID: APPLICATION_FAULT_CLR_EXCEPTION_mscorwks!RaiseTheExceptionInternalOnly+2a8
WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/MiniDumpTest_exe/1_0_0_0/4ab9b640/unknown/0_0_0_0/bbbbbbb4/80000003/00000000.htm?Retriage=1
Followup: MachineOwner
---------
0:000> lm
start end module name
00400000 00408000 MiniDumpTest C (private pdb symbols) d:\work\visual studio.net\minidumptest\minidumptest\bin\release\MiniDumpTest.pdb
00c80000 00da1000 dbghelp (pdb symbols) c:\symbols\dbghelp.pdb\99A1A8F3877B4CA5BEEADFB737F52EB61\dbghelp.pdb
5d090000 5d12a000 comctl32_5d090000 (pdb symbols) c:\symbols\comctl32.pdb\C8EC4F392822448D8560DC2A0D0B56392\comctl32.pdb
74ad0000 74ad8000 powrprof (pdb symbols) c:\windows\symbols\dll\powrprof.pdb
76390000 763ad000 imm32 (pdb symbols) c:\windows\symbols\dll\imm32.pdb
773d0000 774d3000 comctl32 (pdb symbols) c:\symbols\MicrosoftWindowsCommon-Controls-6.0.2600.2982-comctl32.pdb\C0A72EE9578847AAB7770CF02FFED0941\MicrosoftWindowsCommon-Controls-6.0.2600.2982-comctl32.pdb
774e0000 7761d000 ole32 (pdb symbols) c:\symbols\ole32.pdb\683B65B246F4418796D2EE6D4C55EB112\ole32.pdb
77c10000 77c68000 msvcrt (pdb symbols) c:\windows\symbols\dll\msvcrt.pdb
77dd0000 77e6b000 advapi32 (pdb symbols) c:\symbols\advapi32.pdb\79F28EA4A1F4480CAC8106AA928A3F242\advapi32.pdb
77e70000 77f01000 rpcrt4 (pdb symbols) c:\symbols\rpcrt4.pdb\94329756A2824C44A3F5BFE7225FA2422\rpcrt4.pdb
77f10000 77f58000 gdi32 (pdb symbols) c:\symbols\gdi32.pdb\86943752C47D4C9EB370DBCB74734E412\gdi32.pdb
77f60000 77fd6000 shlwapi (pdb symbols) c:\symbols\shlwapi.pdb\658B2B7C863842A0BE311E436027F6E32\shlwapi.pdb
78130000 781cb000 msvcr80 (private pdb symbols) c:\windows\symbols\dll\msvcr80.i386.pdb
79000000 79046000 mscoree (pdb symbols) c:\symbols\mscoree.pdb\FD8F3AA213F243BEA120EC4CF5797BC32\mscoree.pdb
79060000 790bb000 mscorjit (pdb symbols) c:\symbols\mscorjit.pdb\934D5C2DD37F4A8EA01C91DC700F6EC42\mscorjit.pdb
790c0000 79bb7000 mscorlib_ni C (pdb symbols) c:\symbols\mscorlib.pdb\4881A0A3C5B74C1E9C204B1871B8890D1\mscorlib.pdb
79e70000 7a400000 mscorwks (pdb symbols) c:\symbols\mscorwks.pdb\BC2AE2156937489A8A4DAB62BD7E5C932\mscorwks.pdb
7a440000 7abc5000 System_ni C (pdb symbols) c:\symbols\System.pdb\2EE070FC24024C3386DDCBB1297806731\System.pdb
7c800000 7c8f5000 kernel32 (pdb symbols) c:\symbols\kernel32.pdb\4CD38B3D90FF4A919CD8FC60762EE4B32\kernel32.pdb
7c900000 7c9b2000 ntdll (pdb symbols) c:\symbols\ntdll.pdb\A618C674A4FC40F5B1781029C2C7F68E2\ntdll.pdb
7c9c0000 7d1d7000 shell32 (pdb symbols) c:\symbols\shell32.pdb\64CF10584B774D71BBD708BE7D8A05602\shell32.pdb
7e410000 7e4a0000 user32 (pdb symbols) c:\symbols\user32.pdb\92D15332471547DCA0D75061B8B6CDA42\user32.pdb
I'm using the following versions: WinDbg/dbghelp.dll: 6.11.1.404 .NET Framework: 2.0
How do I get the source line information out of the call stack?
The following worked:
Prerequisites: Debugging Tools for Windows installed
Managed interface C++/CLI
DbgHelpNet.h:
// DbgHelpNet.h
#pragma once
#include <dbghelp.h>
using namespace System;
using namespace System;
using namespace System::IO;
using namespace System::Diagnostics;
using namespace System::Runtime::InteropServices;
using namespace System::Configuration;
namespace DbgHelpNet {
/// <summary>Defines the information density of the mini dump (see MINIDUMP_TYPE on MSDN)</summary>
public enum class MiniDumpTypeEnumeration
{
MiniDumpNormal = 0x00000000,
MiniDumpWithDataSegs = 0x00000001,
MiniDumpWithFullMemory = 0x00000002,
MiniDumpWithHandleData = 0x00000004,
MiniDumpFilterMemory = 0x00000008,
MiniDumpScanMemory = 0x00000010,
MiniDumpWithUnloadedModules = 0x00000020,
MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
MiniDumpFilterModulePaths = 0x00000080,
MiniDumpWithProcessThreadData = 0x00000100,
MiniDumpWithPrivateReadWriteMemory = 0x00000200,
MiniDumpWithoutOptionalData = 0x00000400,
MiniDumpWithFullMemoryInfo = 0x00000800,
MiniDumpWithThreadInfo = 0x00001000,
MiniDumpWithCodeSegs = 0x00002000,
MiniDumpWithoutAuxiliaryState = 0x00004000,
MiniDumpWithFullAuxiliaryState = 0x00008000,
MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
MiniDumpIgnoreInaccessibleMemory = 0x00020000,
MiniDumpValidTypeFlags = 0x0000ffff,
};
public ref class MiniDumpWriteDump
{
public:
static void MiniDumpWriteDump::WriteDump(String^ path);
static void MiniDumpWriteDump::WriteDump(String^ path, IntPtr exceptionPointers, MiniDumpTypeEnumeration MiniDumpType);
};
}
DbgHelpNet.cpp:
// This is the main DLL file.
#include "stdafx.h"
#include "DbgHelpNet.h"
#include <dbghelp.h>
#pragma comment( lib, "dbghelp")
namespace DbgHelpNet
{
void MiniDumpWriteDump::WriteDump(String^ path)
{
IntPtr pep = System::Runtime::InteropServices::Marshal::GetExceptionPointers();
WriteDump(path, IntPtr(pep), MiniDumpTypeEnumeration::MiniDumpWithFullMemory);
}
void MiniDumpWriteDump::WriteDump(String^ path, IntPtr exceptionPointers, MiniDumpTypeEnumeration MiniDumpType)
{
PEXCEPTION_POINTERS pep = reinterpret_cast<PEXCEPTION_POINTERS>(exceptionPointers.ToPointer());
MINIDUMP_EXCEPTION_INFORMATION mdei = {GetCurrentThreadId(),pep,FALSE};
MINIDUMP_TYPE miniDumpType = static_cast<MINIDUMP_TYPE>(MiniDumpType);
System::IO::FileStream^ fileStream = File::Create( path );
BOOL blnMiniDumpWriteDumpRetVal = ::MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
fileStream->Handle.ToPointer(),
miniDumpType,
(pep != NULL) ? &mdei : NULL,
NULL,
NULL);
fileStream->Close();
if(blnMiniDumpWriteDumpRetVal)
{
Trace::WriteLine("Successfully created minidump.");
}
else
{
Trace::TraceError( String::Format("Failed to create minidump! Last Error: {0}",GetLastError() ));
}
}
}
Test Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;
namespace MiniDumpTest
{
class Program {
static void Main(string[] args) {
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Console.WriteLine("started");
try {
Console.WriteLine(MyFunc());
} finally {
Console.WriteLine("finished");
Console.ReadLine();
}
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
Console.WriteLine("CurrentDomain_UnhandledException");
DbgHelpNet.MiniDumpWriteDump.WriteDump(@"c:\temp\MyDump.dmp");
Console.WriteLine("MiniDump written");
}
static int MyFunc() {
int i = 0;
++i;
if (i == 1) {
throw new ApplicationException("bla");
}
return i;
}
}
}
Windbg (6.7.5.0):
0:000> k 100
ChildEBP RetAddr
0012f30c 79eda99c kernel32!RaiseException+0x53
0012f36c 79fb48f8 mscorwks!RaiseTheExceptionInternalOnly+0x2a8
0012f430 00d08408 mscorwks!JIT_Throw+0xfc
0012f448 00d000dc MiniDumpTest!MiniDumpTest.Program.MyFunc()+0x70 [c:\temp\MiniDumpTest\MiniDumpTest\Program.cs @ 40]
0012f480 79e71b4c MiniDumpTest!MiniDumpTest.Program.Main(System.String[])+0x6c [c:\temp\MiniDumpTest\MiniDumpTest\Program.cs @ 18]
0012f490 79e821f9 mscorwks!CallDescrWorker+0x33
0012f510 79e96571 mscorwks!CallDescrWorkerWithHandler+0xa3
0012f648 79e965a4 mscorwks!MethodDesc::CallDescr+0x19c
0012f664 79e965c2 mscorwks!MethodDesc::CallTargetWorker+0x1f
0012f67c 79eefac5 mscorwks!MethodDescCallSite::CallWithValueTypes+0x1a
0012f7e0 79eef9e5 mscorwks!ClassLoader::RunMain+0x223
0012fa48 79eeff35 mscorwks!Assembly::ExecuteMainMethod+0xa6
0012ff18 79ef011f mscorwks!SystemDomain::ExecuteMainMethod+0x456
0012ff68 79ef004f mscorwks!ExecuteEXE+0x59
0012ffb0 79007c24 mscorwks!_CorExeMain+0x15c
0012ffc0 7c817077 mscoree!_CorExeMain+0x2c
0012fff0 00000000 kernel32!BaseProcessStart+0x23
User contributions licensed under CC BY-SA 3.0