Pat*_*irk 5 c# c++ windbg crash-dumps
我有一个托管(C#)应用程序的x64故障转储,它可以调用本机代码.在本机代码尝试取消引用错误的内存位置之后,以及在.NET编组程序将其转换为内存之后,转储被执行AccessViolationException.因此,发生错误的堆栈帧不再可用,发生异常的线程现在被CLR异常处理程序劫持:
0:017> kb
# RetAddr : Args to Child : Call Site
00 000007fe`fd3b10dc : 00000000`0402958b 00000000`20000002 00000000`00000e54 00000000`00000e4c : ntdll!NtWaitForSingleObject+0xa
01 000007fe`ea9291eb : 00000000`00000000 00000000`00000cdc 00000000`00000000 00000000`00000cdc : KERNELBASE!WaitForSingleObjectEx+0x79
02 000007fe`ea929197 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : clr!CLREventWaitHelper2+0x38
03 000007fe`ea929120 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : clr!CLREventWaitHelper+0x1f
04 000007fe`ead8cae5 : 00000000`29cbc7c0 00000000`3213ce40 00000000`00000000 00000000`ffffffff : clr!CLREventBase::WaitEx+0x70
05 000007fe`ead8c9d0 : 00000000`29cbc7c0 00000000`00000000 00000000`0002b228 00000000`0002b228 : clr!Thread::WaitSuspendEventsHelper+0xf5
06 000007fe`eacf2145 : 00000000`007ea060 000007fe`ea924676 00000000`00000000 000007fe`fd3b18da : clr!Thread::WaitSuspendEvents+0x11
07 000007fe`eaccc00c : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : clr!Thread::RareEnablePreemptiveGC+0x33a905
08 000007fe`eae2c762 : 00000000`00000000 00000000`007cbce0 00000000`29cbc7c0 00000000`00000001 : clr!Thread::RareDisablePreemptiveGC+0x31b40c
09 000007fe`eaf662d4 : 00000000`00000000 00000000`007cbce0 00000000`29cbc7c0 00000000`00000000 : clr!EEDbgInterfaceImpl::DisablePreemptiveGC+0x22
0a 000007fe`eaf66103 : 00000000`29cb0100 00000000`00000000 00000000`3213cf80 00000000`29cbca20 : clr!Debugger::SendExceptionHelperAndBlock+0x174
0b 000007fe`eaf65d0d : ffffffff`ffffffff 00000000`29cbca20 00000000`29cbc700 000007fe`eaf62100 : clr!Debugger::SendExceptionEventsWorker+0x343
0c 000007fe`eaf61bd8 : 00000000`00000100 00000000`00000000 00000000`00000019 00000000`3213dd01 : clr!Debugger::SendException+0x15d
0d 000007fe`eadac75d : 00000000`007cbce0 00000000`3213d258 00000000`3213d1e8 00000000`00000001 : clr!Debugger::LastChanceManagedException+0x1f8
0e 000007fe`eaf698c7 : 000075ce`2b30e018 00000000`00000000 00000000`00000001 00000000`00000000 : clr!NotifyDebuggerLastChance+0x6d
0f 000007fe`eaf6af20 : 00000000`00000000 000007fe`8cf40020 000007fe`8cfa200c 4328fffe`43e0fffe : clr!Debugger::UnhandledHijackWorker+0x1a7
10 000007fe`eaaacbf0 : 00000000`0000000a 00000000`2ab23e30 00000000`00000001 00000000`00000000 : clr!ExceptionHijackWorker+0xc0
11 00000000`3213d8c0 : 00000000`3213ddb0 00000000`00000001 00000000`00000000 00000000`0000000b : clr!ExceptionHijack+0x30
12 00000000`3213ddb0 : 00000000`00000001 00000000`00000000 00000000`0000000b 00000000`0035578c : 0x3213d8c0
13 00000000`00000001 : 00000000`00000000 00000000`0000000b 00000000`0035578c ffffffff`00000002 : 0x3213ddb0
14 00000000`00000000 : 00000000`0000000b 00000000`0035578c ffffffff`00000002 00000000`00350268 : 0x1
Run Code Online (Sandbox Code Playgroud)
并且.exr -1(显示最近的异常)返回:
0:017> .exr -1
ExceptionAddress: 00000000771d685a (user32!ZwUserMessageCall+0x000000000000000a)
ExceptionCode: 80000004 (Single step exception)
ExceptionFlags: 00000000
NumberParameters: 0
Run Code Online (Sandbox Code Playgroud)
调用user32!ZwUserMessageCall是在线程0的堆栈顶部,而不是发生本机异常的17,所以我只能假设它没有指向我的异常.
我可以转储访问冲突异常以获取有关本机错误的一些信息:
0:017> !DumpObj /d 0000000012175640
Name: System.AccessViolationException
MethodTable: 000007fee9a61fe8
EEClass: 000007fee9528300
Size: 176(0xb0) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007fee9a50e08 4000002 8 System.String 0 instance 000000001217b538 _className
000007fee9a5b218 4000003 10 ...ection.MethodBase 0 instance 0000000000000000 _exceptionMethod
000007fee9a50e08 4000004 18 System.String 0 instance 0000000000000000 _exceptionMethodString
000007fee9a50e08 4000005 20 System.String 0 instance 0000000012179818 _message
000007fee9a61f18 4000006 28 ...tions.IDictionary 0 instance 0000000000000000 _data
000007fee9a51038 4000007 30 System.Exception 0 instance 0000000000000000 _innerException
000007fee9a50e08 4000008 38 System.String 0 instance 0000000000000000 _helpURL
000007fee9a513e8 4000009 40 System.Object 0 instance 0000000012179ad0 _stackTrace
000007fee9a513e8 400000a 48 System.Object 0 instance 0000000012179c68 _watsonBuckets
000007fee9a50e08 400000b 50 System.String 0 instance 0000000000000000 _stackTraceString
000007fee9a50e08 400000c 58 System.String 0 instance 0000000000000000 _remoteStackTraceString
000007fee9a53980 400000d 88 System.Int32 1 instance 0 _remoteStackIndex
000007fee9a513e8 400000e 60 System.Object 0 instance 0000000000000000 _dynamicMethods
000007fee9a53980 400000f 8c System.Int32 1 instance -2147467261 _HResult
000007fee9a50e08 4000010 68 System.String 0 instance 0000000000000000 _source
000007fee9a54a00 4000011 78 System.IntPtr 1 instance 0 _xptrs
000007fee9a53980 4000012 90 System.Int32 1 instance -532462766 _xcode
000007fee9a02d50 4000013 80 System.UIntPtr 1 instance 0 _ipForWatsonBuckets
000007fee9a3d210 4000014 70 ...ializationManager 0 instance 0000000012179900 _safeSerializationManager
000007fee9a513e8 4000001 0 System.Object 0 shared static s_EDILock
>> Domain:Value 00000000007e09b0:NotInit <<
000007fee9a54a00 400018a 98 System.IntPtr 1 instance 7fedad179f4 _ip
000007fee9a54a00 400018b a0 System.IntPtr 1 instance fffffffc2ab22078 _target
000007fee9a53980 400018c 94 System.Int32 1 instance 0 _accessType
Run Code Online (Sandbox Code Playgroud)
从这里我看到失败的指令地址(7fedad179f4)和代码试图取消引用的地址(fffffffc2ab22078).它似乎是某种方式的符号扩展或溢出错误,但在代码中可能发生的情况并不明显.引用的指令是:
0:017> u 7fedad179f4
MYDLL!_interpolate+0x174 [c:\my\source\file.c @ 85]:
000007fe`dad179f4 f3450f59548404 mulss xmm10,dword ptr [r12+rax*4+4]
Run Code Online (Sandbox Code Playgroud)
为了进一步调试这一点,我需要当本地代码崩溃,看看有什么是寄存器上下文r12和rax.这有可能找回来吗?
编辑: 我试图获取有关参数的信息ExceptionHijackWorker,但这些值对我没有意义.根据@ ST的链接的功能签名是
void STDCALL ExceptionHijackWorker(T_CONTEXT * pContext,
EXCEPTION_RECORD * pRecord,
EHijackReason::EHijackReason reason,
void * pData);
Run Code Online (Sandbox Code Playgroud)
所以第一个参数0000000a作为指针是没有意义的.并且转储第二个参数会000000002ab23e30产生以下的无意义数据EXCEPTION_RECORD:
0:017> dd 000000002ab23e30
00000000`2ab23e30 00000019 00000019 2ab23e40 00000000
00000000`2ab23e40 42b8f800 42b8de00 42b89b00 42b85000
00000000`2ab23e50 42b81b00 42b7a000 42b72600 42b6fa00
00000000`2ab23e60 42b6a000 42b67a00 42b63600 42b59c00
00000000`2ab23e70 42b4fc00 42b4da00 42b49e00 42b46a00
00000000`2ab23e80 42b38e00 42b31c00 42b2d600 42b29000
00000000`2ab23e90 42b2ec00 42b2fa00 42b2a000 42b27a00
00000000`2ab23ea0 42b23e00 42b6e800 42b6ab00 42b66c80
Run Code Online (Sandbox Code Playgroud)
0x19而0x19对于ExceptionCode和ExceptionFlags没有意义; 没有具有该值的代码,并且该标志被记录为零或EXCEPTION_NONCONTINUABLE,其被定义为1.
我在这里误解了什么吗?
遵循@ST的建议的建议,我开始探索调用堆栈,看看是否可以找到异常记录或上下文记录。我从堆栈底部的奇怪之处开始,即:
0:017> k
# Child-SP RetAddr Call Site
...
0f 00000000`3213d210 000007fe`eaf6af20 clr!Debugger::UnhandledHijackWorker+0x1a7
10 00000000`3213d850 000007fe`eaaacbf0 clr!ExceptionHijackWorker+0xc0
11 00000000`3213d880 00000000`3213d8c0 clr!ExceptionHijack+0x30
12 00000000`3213d8a8 00000000`3213ddb0 0x3213d8c0
13 00000000`3213d8b0 00000000`00000001 0x3213ddb0
14 00000000`3213d8b8 00000000`00000000 0x1
Run Code Online (Sandbox Code Playgroud)
偶然发现异常记录:
0:017> .exr 00000000`3213ddb0
ExceptionAddress: 000007fedad179f4 (SMTCV!_interpolate+0x0000000000000174)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000000
Parameter[1]: fffffffc2ab22078
Attempt to read from address fffffffc2ab22078
Run Code Online (Sandbox Code Playgroud)
然后我碰巧找到了上下文记录(我正在寻找的内容):
0:017> .cxr 00000000`3213d8c0
rax=0000000000000019 rbx=000000000000000a rcx=00000000709c7c88
rdx=0000000000000002 rsi=000000002ab23e30 rdi=0000000080000000
rip=000007fedad179f4 rsp=000000003213dff0 rbp=0000000000000019
r8=000007ffffe22000 r9=0000000070910000 r10=0000000000000000
r11=000000003213e0a0 r12=fffffffc2ab22010 r13=000000002b50ae40
r14=000000002ab241ec r15=0000000000000003
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=0000 es=0000 fs=0000 gs=0000 efl=00010200
MYDLL!_interpolate+0x174:
000007fe`dad179f4 f3450f59548404 mulss xmm10,dword ptr [r12+rax*4+4] ds:fffffffc`2ab22078=????????
Run Code Online (Sandbox Code Playgroud)
我可以看到我的坏指针r12!
我不明白这些堆栈帧是什么,也不明白为什么异常和上下文记录被存储为它们的返回地址。对于我和未来的读者来说,任何对此的评论都会很棒。