我正在尝试从托管C#应用程序(.NET Framework 2.0)中未处理的异常处理程序中编写一个minidump:
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
}
}
在分析WinDbg中的minidump时,即使PDB匹配并且所有路径(符号,源,图像)都设置正确,调用堆栈中也缺少源行信息。
我在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
我使用以下版本: WinDbg / dbghelp.dll:6.11.1.404 .NET Framework:2.0
如何从调用堆栈中获取源代码行信息?
答案 0 :(得分:1)
以下工作:
先决条件:已安装Windows的调试工具
托管接口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() ));
}
}
}
测试代码:
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&GT; 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