在WinDbg中分析minidump时缺少源行信息

时间:2009-09-23 06:16:41

标签: c# .net

我正在尝试从托管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

如何从调用堆栈中获取源代码行信息?

1 个答案:

答案 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