Re: windbg+sos 调试dotnet release版本的程序堆栈信息问题。
.Net程序调试
windbg+sos 调试dotnet release版本的程序堆栈信息问题。
lzh
2007-04-27, 16:28 下午
用windbg+sos 调试dotnet 程序。为了验证自己的一些想法,写了个简单的例子。
namespace Debug
{
///
/// Summary description for Class1.
///
class Debug
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)
{
Test obj = new Test();
obj.Fun1();
}
}
public class Test
{
public void Fun1()
{
Fun2();
}
private void Fun2()
{
Fun3();
}
private void Fun3()
{
Fun4();
}
private void Fun4()
{
int length =0;
string str = null;
length = str.Length;
this.Fun5(length);
}
private void Fun5(int a)
{
}
}
}
可以看出fun4() 里有null reference问题。
问题是这样的:release版本。用windbg启动调试后,出现异常,看到的调用堆栈只到了Main(),再详细的信息就看不到了。
而Debug版本,出现Access Vialation 后。
用!dumpstack 可以看到详细的调用堆栈
main()-->fun1()-->fun2()--->fun3()-->fun4()--fun5().
这是怎么回事呢,一般产品里的dll 都是release版本的
那样的话,用windbg调试的时候看到的堆栈信息不够全啊。(我已经用了正确的符号)
Re: windbg+sos 调试dotnet release版本的程序堆栈信息问题。
advdbg
2007-04-28, 18:13 下午
LZH, 如果符号正确,应该可以看到完整的栈回溯信息呀。你用使用lm命令检查一下,看你的模块加载的是什么符号。
Re: windbg+sos 调试dotnet release版本的程序堆栈信息问题。
lzh
2007-04-28, 22:05 下午
我看了,有符号。但确实是堆栈信息不完整,你可以试一下。
0:000> lmvm debug
start end module name
00400000 00408000 Debug C (private pdb symbols) E:\Practice\TestVSIDE\Solution1\Debug\bin\Release\Debug.pdb
Loaded symbol image file: E:\Practice\TestVSIDE\Solution1\Debug\bin\Release\Debug.exe
堆栈信息。
0:000> !dumpstack
succeeded
Loaded Son of Strike data table version 5 from "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorwks.dll"
Current frame: (MethodDesc 0xca5080 +0xc Debug.Debug.Main)
ChildEBP RetAddr Caller,Callee
0012f69c 791da94f mscorwks!CallDescrWorker+0x30
0012f6a4 791de31c mscorwks!MethodDesc::CallDescr+0x1b8, calling mscorwks!CallDescrWorker
0012f6d4 791d85aa mscorwks!MetaSig::SizeOfActualFixedArgStack+0x14, calling mscorwks!MetaSig::ForceSigWalk
0012f6e4 791de20e mscorwks!MethodDesc::CallDescr+0x79, calling mscorwks!MetaSig::SizeOfActualFixedArgStack
0012f6e8 791de21e mscorwks!MethodDesc::CallDescr+0x89, calling mscorwks!_chkstk
。。。。
你说会不会是SOS这个调试扩展组件的问题。
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\sos: API 1.0.0, built Sat Feb 19 04:35:47 2005
我用VS2005试了一下也不行。
Re: windbg+sos 调试dotnet release版本的程序堆栈信息问题。
advdbg
2007-04-29, 10:47 上午
我试验了一下,首先使用VS2005是可以的,以下是运行release 版本的Call Stack窗口内容:
> CallStack.exe!CallStack.Test.Fun4() Line 53 C#
CallStack.exe!CallStack.Test.Fun3() Line 47 C#
CallStack.exe!CallStack.Test.Fun2() Line 42 C#
CallStack.exe!CallStack.Test.Fun1() Line 37 C#
CallStack.exe!CallStack.Debug.Main(string[] args = {Dimensions:[0]}) Line 29 C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x32 bytes
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes
Re: windbg+sos 调试dotnet release版本的程序堆栈信息问题。
advdbg
2007-04-29, 11:34 上午
在VS2005的立即窗口,也可以正确的显示:
.load sos
extension C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll loaded
!dumpstack
PDB symbol for mscorwks.dll not loaded
OS Thread Id: 0x1218 (4632)
Current frame: (MethodDesc 0xa73088 +0x1c CallStack.Test.Fun4())
ChildEBP RetAddr Caller,Callee
0012f458 01120169 (MethodDesc 0xa73080 +0x19 CallStack.Test.Fun3()), calling (MethodDesc 0xa73088 +0 CallStack.Test.Fun4())
0012f460 01120139 (MethodDesc 0xa73078 +0x19 CallStack.Test.Fun2()), calling (MethodDesc 0xa73080 +0 CallStack.Test.Fun3())
0012f468 01120109 (MethodDesc 0xa73070 +0x19 CallStack.Test.Fun1()), calling (MethodDesc 0xa73078 +0 CallStack.Test.Fun2())
0012f470 011200a6 (MethodDesc 0xa72fe0 +0x36 CallStack.Debug.Main(System.String[])), calling (MethodDesc 0xa73070 +0 CallStack.Test.Fun1())
0012f480 79e88f63 _CallDescrWorker@20+0x33
0012f490 79e88ee4 _CallDescrWorkerWithHandler@24+0xa3, calling _CallDescrWorker@20
0012f510 79e88e31 ?CallDescr@MethodDesc@@AAE_KPBEPAVMetaSig@@PB_KHH@Z+0x19c, calling _CallDescrWorkerWithHandler@24
0012f540 79e88fe3 ??0MetaSig@@QAE@PAV0@@Z+0x38, calling memcpy [F:\RTM\vctools\crt_bld\SELF_X86\crt\src\intel\memcpy.asm:101]
0012f54c 79e88db3 ?CallDescr@MethodDesc@@AAE_KPBEPAVMetaSig@@PB_KHH@Z+0xaf, calling ?addition@?$ClrSafeInt@I@@SG_NIIAAI@Z
0012f558 79e88dc3 ?CallDescr@MethodDesc@@AAE_KPBEPAVMetaSig@@PB_KHH@Z+0xbb, calling __alloca_probe_16
0012f5bc 79e7c34e ?CorSigEatCustomModifiers@@YGJPAPBEKPAK@Z+0x1c, calling ?CorSigEatAnyVASentinel@@YGJPAPBEKPAK@Z
0012f5d8 79e7c301 ?CorSigEatCustomModifiersAndUncompressElementType@@YGJPAPBEKPAKPAW4CorElementType@@@Z+0x19, calling ?CorSigEatCustomModifiers@@YGJPAPBEKPAK@Z
0012f5f4 79f0776d ?ValidateMainMethod@@YGXPAVMethodDesc@@PAW4CorEntryPointType@@@Z+0x15c, calling ?CorSigEatCustomModifiersAndUncompressElementType@@YGJPAPBEKPAKPAW4CorElementType@@@Z
0012f60c 79e88d3b ?CallDescr@MethodDesc@@AAE_KPBEPAVMetaSig@@PB_KHH@Z+0x1f, calling __alloca_probe_16
0012f650 79e88d19 ?CallTargetWorker@MethodDesc@@AAE_KPBEPAVMetaSig@@PB_KH@Z+0x20, calling ?CallDescr@MethodDesc@@AAE_KPBEPAVMetaSig@@PB_KHH@Z
0012f668 79e88cf6 ?Call@MethodDescCallSite@@QAEXPB_K@Z+0x18, calling ?CallTargetWorker@MethodDesc@@AAE_KPBEPAVMetaSig@@PB_KH@Z
0012f67c 79f084b0 ?RunMain@ClassLoader@@KGJPAVMethodDesc@@FPAHPAPAVPtrArray@@@Z+0x220, calling ?Call@MethodDescCallSite@@QAEXPB_K@Z
0012f788 79e7c34e ?CorSigEatCustomModifiers@@YGJPAPBEKPAK@Z+0x1c, calling ?CorSigEatAnyVASentinel@@YGJPAPBEKPAK@Z
0012f7a4 79e7c301 ?CorSigEatCustomModifiersAndUncompressElementType@@YGJPAPBEKPAKPAW4CorElementType@@@Z+0x19, calling ?CorSigEatCustomModifiers@@YGJPAPBEKPAK@Z
0012f7c0 79f0776d ?ValidateMainMethod@@YGXPAVMethodDesc@@PAW4CorEntryPointType@@@Z+0x15c, calling ?CorSigEatCustomModifiersAndUncompressElementType@@YGJPAPBEKPAKPAW4CorElementType@@@Z
0012f7e0 79f082a9 ?ExecuteMainMethod@Assembly@@QAEHPAPAVPtrArray@@@Z+0xa6, calling ?RunMain@ClassLoader@@KGJPAVMethodDesc@@FPAHPAPAVPtrArray@@@Z
0012f838 79e74753 ?Leave@CrstBase@@AAEXXZ+0x96, calling __EH_epilog3
0012f85c 79e77fe8 ?LoadImage@PEImage@@SGPAV1@PAUHINSTANCE__@@@Z+0x1e1, calling __SEH_epilog4
0012f888 7c926abe _RtlFreeHeapSlowly@12+0x5c2, calling __SEH_epilog
0012f88c 7c9268ad _RtlFreeHeap@12+0xf9, calling _RtlFreeHeapSlowly@12
0012f898 7c91056d _RtlFreeHeap@12+0x647, calling __SEH_epilog
0012f8bc 79e783e6 ?EEHeapFree@@YGHPAXK0@Z+0xa5, calling __EH_epilog3
0012f8c0 79e7839d ?EEHeapFreeInProcessHeap@@YGHKPAX@Z+0x21, calling ?EEHeapFree@@YGHPAXK0@Z
0012f8cc 79f6e717 ??1?$BaseWrapper@PCJV?$FunctionBase@PCJ$1?CounterIncrease@@YGXPCJ@Z$1?CounterDecrease@@YGX0@Z$0A@@@$0A@$1??$CompareDefault@PCJ@@YGHPCJ0@Z$0A@@@QAE@XZ+0x23, calling _InterlockedDecrement@4
0012f8e0 79e77f9f ?WaitEx@CLREvent@@QAEKKW4WaitMode@@PAUPendingSync@@@Z+0x11c, calling __EH_epilog3
0012f8e4 79e77f50 ?Wait@CLREvent@@QAEKKHPAUPendingSync@@@Z+0x17, calling ?WaitEx@CLREvent@@QAEKKW4WaitMode@@PAUPendingSync@@@Z
0012f8f0 79e786aa ?CleanupTry@HandlerState@CLRException@@QAEXXZ+0x13, calling ?GetCurrentSEHRecord@@YGPAU_EXCEPTION_REGISTRATION_RECORD@@XZ
0012f900 7a0dd77e ?WaitSuspendEventsHelper@Thread@@AAEHXZ+0xd6, calling ?CleanupTry@HandlerState@CLRException@@QAEXXZ
0012f904 79e7a39e __EH_epilog3_catch_GS+0xa, calling @__security_check_cookie@4
0012f908 7a0dd7b3 ?WaitSuspendEventsHelper@Thread@@AAEHXZ+0x10b, calling __EH_epilog3_catch_GS
0012f944 7c80a027 _SetEvent@4+0x10, calling _ZwSetEvent@8
0012f958 7c91056d _RtlFreeHeap@12+0x647, calling __SEH_epilog
0012f95c 79e783ca ?EEHeapFree@@YGHPAXK0@Z+0x83, calling _RtlFreeHeap@12
0012f968 79e783e6 ?EEHeapFree@@YGHPAXK0@Z+0xa5, calling __EH_epilog3
0012f980 79f75952 ?__DangerousSwitchToThread@@YGHKH@Z+0xe3, calling __EH_epilog3
0012f990 79e783e6 ?EEHeapFree@@YGHPAXK0@Z+0xa5, calling __EH_epilog3
0012f994 79e7839d ?EEHeapFreeInProcessHeap@@YGHKPAX@Z+0x21, calling ?EEHeapFree@@YGHPAXK0@Z
0012f9a4 79e71862 ??1SaveLastErrorHolder@@QAE@XZ+0x14, calling _RtlGetLastWin32Error@0
0012f9ac 79e782ed ??_V@YAXPAX@Z+0x41, calling __EH_epilog3
0012f9d4 79e782ed ??_V@YAXPAX@Z+0x41, calling __EH_epilog3
0012f9d8 79e7a9ff ??1?$SArray@PAVMethodDesc@@$00@@QAE@XZ+0x21, calling ??_V@YAXPAX@Z
0012f9dc 79e7a9f6 ??1?$SArray@PAVMethodDesc@@$00@@QAE@XZ+0x27, calling __EH_epilog3
0012f9fc 79e7a9f6 ??1?$SArray@PAVMethodDesc@@$00@@QAE@XZ+0x27, calling __EH_epilog3
0012fa20 79e7a9f6 ??1?$SArray@PAVMethodDesc@@$00@@QAE@XZ+0x27, calling __EH_epilog3
0012fa24 79e7ee67 ??1?$InlineSString@$0MI@@@QAE@XZ+0x1d, calling __EH_epilog3
0012fa38 79e7a773 ?EnablePreemptiveGC@Thread@@QAEXXZ+0xf, calling ?CatchAtSafePoint@Thread@@QAEKXZ
0012fa48 79f0817e ?ExecuteMainMethod@SystemDomain@@SGXPAUHINSTANCE__@@PAG@Z+0x398, calling ?ExecuteMainMethod@Assembly@@QAEHPAPAVPtrArray@@@Z
0012fb4c 79e782ed ??_V@YAXPAX@Z+0x41, calling __EH_epilog3
0012fb50 79e8dd55 ?Clear@CStructArray@@QAEXXZ+0x15, calling ??_V@YAXPAX@Z
0012fb60 79e87b53 ?CommonGetCustomAttributeByName@CMiniMd@@MAEJIPBDPAPBXPAK@Z+0x7a, calling ?ClearEnum@HENUMInternal@@SGXPAU1@@Z
0012fb68 79e8837c ?GetBinarySig@HardCodedMetaSig@@QBEXPAPBEPAK@Z+0x146, calling __EH_epilog3
0012fb94 7c926abe _RtlFreeHeapSlowly@12+0x5c2, calling __SEH_epilog
0012fb98 7c9268ad _RtlFreeHeap@12+0xf9, calling _RtlFreeHeapSlowly@12
0012fba4 7c91056d _RtlFreeHeap@12+0x647, calling __SEH_epilog
0012fbbc 7c919bd3 _LdrpSnapThunk@32+0xbd, calling _LdrpNameToOrdinal@20
0012fbfc 7c910895 _RtlImageDirectoryEntryToData@16+0x57, calling _RtlpImageDirectoryEntryToData32@20
0012fc0c 7c919a9c _LdrpGetProcedureAddress@20+0x186, calling _LdrpSnapThunk@32
0012fc24 7c919b3f _LdrpGetProcedureAddress@20+0x29b, calling _RtlLeaveCriticalSection@4
0012fc2c 7c919aeb _LdrpGetProcedureAddress@20+0xa6, calling __SEH_epilog
0012fc9c 79f6e717 ??1?$BaseWrapper@PCJV?$FunctionBase@PCJ$1?CounterIncrease@@YGXPCJ@Z$1?CounterDecrease@@YGX0@Z$0A@@@$0A@$1??$CompareDefault@PCJ@@YGHPCJ0@Z$0A@@@QAE@XZ+0x23, calling _InterlockedDecrement@4
0012fcb0 79e77f9f ?WaitEx@CLREvent@@QAEKKW4WaitMode@@PAUPendingSync@@@Z+0x11c, calling __EH_epilog3
0012fcb4 79e77f50 ?Wait@CLREvent@@QAEKKHPAUPendingSync@@@Z+0x17, calling ?WaitEx@CLREvent@@QAEKKW4WaitMode@@PAUPendingSync@@@Z
0012fcc0 79e786aa ?CleanupTry@HandlerState@CLRException@@QAEXXZ+0x13, calling ?GetCurrentSEHRecord@@YGPAU_EXCEPTION_REGISTRATION_RECORD@@XZ
0012fcd4 7c919aeb _LdrpGetProcedureAddress@20+0xa6, calling __SEH_epilog
0012fcd8 7c919ba0 _LdrGetProcedureAddress@16+0x18, calling _LdrpGetProcedureAddress@20
0012fcf4 7c80adde _GetProcAddress@8+0x43, calling _LdrGetProcedureAddress@16
0012fcfc 7c80adf0 _GetProcAddress@8+0x5b, calling _BasepMapModuleHandle@8
0012fd98 79ed474d ??1?$Holder@PAVDebugger@@$1?AcquireDebuggerLock@1@CGXPAV1@@Z$1?ReleaseDebuggerLock@1@CGX0@Z$0A@$1??$CompareDefault@PAVDebugger@@@@YGH00@Z$01@@QAE@XZ+0x2b, calling __EH_epilog3
0012fd9c 7a2a796b ?SendCreateAppDomainEvent@Debugger@@QAEXPAVAppDomain@@H@Z+0x143, calling __EH_epilog3
0012fdb0 79e8837c ?GetBinarySig@HardCodedMetaSig@@QBEXPAPBEPAK@Z+0x146, calling __EH_epilog3
0012fdb4 79e8a800 ?FetchMethod@Binder@@QAEPAVMethodDesc@@W4BinderMethodID@@@Z+0x5a, calling ?GetBinarySig@HardCodedMetaSig@@QBEXPAPBEPAK@Z
0012fdcc 79e83493 ?CheckInit@Binder@@CGXPAVMethodTable@@@Z+0xb, calling ?IsClassInited@MethodTable@@QAEHPAVAppDomain@@@Z
0012fdd4 79e8a797 ?GetMethod@Binder@@QAEPAVMethodDesc@@W4BinderMethodID@@@Z+0x63, calling ?CheckInit@Binder@@CGXPAVMethodTable@@@Z
0012fdd8 79e8a7ab ?GetMethod@Binder@@QAEPAVMethodDesc@@W4BinderMethodID@@@Z+0x79, calling __EH_epilog3
0012fddc 79ebfe27 ?GetActionOnFailure@EEPolicy@@QAE?AW4__MIDL___MIDL_itf_mscoree_0151_0004@@W4__MIDL___MIDL_itf_mscoree_0151_0002@@@Z+0x8f, calling __EH_epilog3
0012fe00 79e786aa ?CleanupTry@HandlerState@CLRException@@QAEXXZ+0x13, calling ?GetCurrentSEHRecord@@YGPAU_EXCEPTION_REGISTRATION_RECORD@@XZ
0012fe10 79eb80fa ?EEStartupHelper@@YGXW4tagCOINITEE@@@Z+0x7a3, calling ?CleanupTry@HandlerState@CLRException@@QAEXXZ
0012fe28 79eb8141 ?EEStartupHelper@@YGXW4tagCOINITEE@@@Z+0x8d2, calling @__security_check_cookie@4
0012fe4c 79ed91f3 ?InitOptionalConfigCache@REGUTIL@@SGXXZ+0x186, calling ?CaseCompareHelper@SString@@CGHPBG0IKHH@Z
0012feb8 7c9106eb _RtlAllocateHeap@12+0xeac, calling __SEH_epilog
0012febc 79e78360 ?EEHeapAlloc@@YGPAXPAXKK@Z+0x12d, calling _RtlAllocateHeap@12
0012feec 79ebc7d8 ?EEStartup@@YGJW4tagCOINITEE@@@Z+0x50, calling ?EEStartupHelper@@YGXW4tagCOINITEE@@@Z
0012fef0 79ebc7f7 ?EEStartup@@YGJW4tagCOINITEE@@@Z+0x75, calling __SEH_epilog4
0012ff18 79f07dc7 ?ExecuteEXE@@YGHPAUHINSTANCE__@@@Z+0x59, calling ?ExecuteMainMethod@SystemDomain@@SGXPAUHINSTANCE__@@PAG@Z
0012ff68 79f05f61 __CorExeMain@0+0x11b, calling ?ExecuteEXE@@YGHPAUHINSTANCE__@@@Z
0012ff74 7c9106eb _RtlAllocateHeap@12+0xeac, calling __SEH_epilog
0012ffb0 79011b5f __CorExeMain@0+0x2c
0012ffc0 7c816fd7 _BaseProcessStart@4+0x23
0012ffc4 7c9106eb _RtlAllocateHeap@12+0xeac, calling __SEH_epilog
Re: windbg+sos 调试dotnet release版本的程序堆栈信息问题。
advdbg
2007-04-29, 13:04 下午
在WinDbg中,对于调试版本,显示的结果和上面在立即窗口中的很类似,也就是可以显示到Func3/4。但是对于发布版本,的确只能显示到Main函数。
0:000> !dumpstack -ee
OS Thread Id: 0x1014 (0)
Current frame: (MethodDesc 0xa72fe0 +0xa CallStack.Debug.Main(System.String[]))
ChildEBP RetAddr Caller,Callee
Re: windbg+sos 调试dotnet release版本的程序堆栈信息问题。
lzh
2007-04-29, 13:33 下午
是,在VisualStudio里面可以。
那是不是说明VisualStudio 内部用的调试引擎 和windbg不一样?
SOS都是一样的
Re: windbg+sos 调试dotnet release版本的程序堆栈信息问题。
advdbg
2007-04-29, 23:10 下午
使用exr命令可以看到导致异常的地址是00fe007a:
0:000> .exr -1
ExceptionAddress: 00fe007a
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 00000000
Attempt to read from address 00000000
这个地址不属于任何模块,它是由子节码动态编译产生的,这也是为什么使用本地的kv命令会失败的原因:
0:000> kv
ChildEBP RetAddr Args to Child
WARNING: Frame IP not in any known module. Following frames may be wrong.
0012f480 79e88f63 00000000 0012f4b8 0012f510 0xfe007a
...
使用 SOS的!dumpmd 方法观察dumpstack中给出的MethodDesc结构:
0:000> !dumpmd 0xa72fe0
Method Name: CallStack.Debug.Main(System.String[])
Class: 00a7128c
MethodTable: 00a72ff0
mdToken: 06000001
Module: 00a72c14
IsJitted: yes
m_CodeOrIL: 00fe0070
比较m_CodeOrIL字段的值00fe0070和导致异常的值,二者非常近。
对00fe0070反汇编:
0:000> u 00fe0070
00fe0070 b9a030a700 mov ecx,0A730A0h
00fe0075 e8a21fa8ff call 00a6201c
00fe007a 390500000000 cmp dword ptr ds:[0],eax
00fe0080 c3 ret
可以看到00fe007a处就是导致异常的指令。看来dumpstack没有错,异常真地在Main方法中。
那到底怎么回事呢?笔者推测,这是因为在发布版本中,main函数调用FuncX的过程被优化掉了。