Windows 上的 ExceptionHandler 堆栈跟踪
ExceptionHandler stacktrace on Windows
所以,我在我正在查看的转储 (x86/Windows 7) 的调用堆栈之一中看到了这一行。由于我的问题仅与此电话有关,因此我已将其大量删除。
Args to Child
01111111 04444444 05555555 ntdll!KiUserExceptionDispatcher+0xf
经过:http://www.nynaeve.net/Code/KiUserExceptionDispatcher.c
看起来堆栈上的前两个参数必须是上下文记录和异常记录。然而,通过一些实验,我注意到 01111111
不是第一个参数。它实际上是从 04444444
开始的。因此,在这种情况下 .cxr 04444444
和 .exr 05555555
显示正常的输出。
现在,我知道调试器可能只显示此时堆栈上的任何内容,我可能不应该单独依赖它,但是如果下面那一行都被标记了使用 "stack unwind information not available. Following frames may be wrong",我怎么知道我应该忽略 01111111?
更新
让我们试试不同的方法。以下是 2 条相关信息:
Args to Child
0ccccccc 77895ac4 00000000 kernel32!UnhandledExceptionFilter+0x9e
[... various other calls here, leading up to ...]
0eeeeeee 0aaaaaaa 0bbbbbbb ntdll!KiUserExceptionDispatcher+0xf
所以,检查一下。 UnhandledExceptionFilter
的唯一参数是一个 EXCEPTION_POINTERS* 结构,对吗?
0:010> dd 0ccccccc l2
0ddddddd 0bbbbbbb 0aaaaaaa
在 EXCEPTION_POINTERS 结构中,第一个字段是 EXCEPTION_RECORD (0bbbbbbb),而第二个字段是 CONTEXT_RECORD (0aaaaaaa)。然而,在对 KiUserEceptionDispatcher 的调用中,这些参数以相反的方式出现。更不用说 0eeeeeee NOT 是 KiUserExceptionDispatcher 的第一个参数,但 0ccccccc IS 是 UnhandledExceptionFilter 的第一个参数。
我很困惑!
windows 7 x86 32位机
winkey + r -> windbg 计算
bp ntdll!KiUserExceptionDispatcher
f5
在计算器中除以 0/0 以引发异常
(ac8.c8c): C++ EH exception - code e06d7363 (first chance)
Breakpoint 0 hit
eax=0023e1ec ebx=02b12fd0 ecx=00000003 edx=00000000 esi=02b13178 edi=00000001
eip=76e77048 esp=0023dee0 ebp=0023e23c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!KiUserExceptionDispatcher:
76e77048 fc cld
你的 post 显示 return 地址为 + 0xf 所以让我们看看到那一点
0:000> u . .+f
ntdll!KiUserExceptionDispatcher:
76e77048 fc cld
76e77049 8b4c2404 mov ecx,dword ptr [esp+4]
76e7704d 8b1c24 mov ebx,dword ptr [esp]
76e77050 51 push ecx
76e77051 53 push ebx
76e77052 e85d88fdff call ntdll!RtlDispatchException (76e4f8b4)
76e77057 0ac0 or al,al
看来您在从调用堆栈中输入 RtlDispatchException 后出现故障
打破进入通话
0:000> tc
eax=0023e1ec ebx=0023dee8 ecx=0023df08 edx=00000000 esi=02b13178 edi=00000001
eip=76e77052 esp=0023ded8 ebp=0023e23c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!KiUserExceptionDispatcher+0xa:
76e77052 e85d88fdff call ntdll!RtlDispatchException (76e4f8b4)
0:000> t
eax=0023e1ec ebx=0023dee8 ecx=0023df08 edx=00000000 esi=02b13178 edi=00000001
eip=76e4f8b4 esp=0023ded4 ebp=0023e23c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!RtlDispatchException:
76e4f8b4 8bff mov edi,edi
查看堆栈,如果您要求 windbg 冗长,它甚至会为您破译上下文
0:000> kb 3
# ChildEBP RetAddr Args to Child
00 0023ded0 76e77057 0023dee8 0023df08 0023dee8 ntdll!RtlDispatchException
01 0023ded0 7521b760 0023dee8 0023df08 0023dee8 ntdll!KiUserExceptionDispatcher+0xf
02 0023e23c 7579359c e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58
0:000> kv 3
# ChildEBP RetAddr Args to Child
00 0023ded0 76e77057 0023dee8 0023df08 0023dee8 ntdll!RtlDispatchException (FPO: [Non-Fpo])
01 0023ded0 7521b760 0023dee8 0023df08 0023dee8 ntdll!KiUserExceptionDispatcher+0xf (FPO: [2,0,0]) (CONTEXT @ 0023df08)
02 0023e23c 7579359c e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58 (FPO: [Non-Fpo])
exr 输出
0:000> .exr poi(@esp+4)
ExceptionAddress: 7521b760 (KERNELBASE!RaiseException+0x00000058)
ExceptionCode: e06d7363 (C++ EH exception)
ExceptionFlags: 00000001
NumberParameters: 3
Parameter[0]: 19930520
Parameter[1]: 0023e294
Parameter[2]: 007c15b4
unable to find C-Runtime symbols, even with unqualified search
上下文记录输出
0:000> dt ntdll!_CONTEXT poi(@esp+8)
+0x000 ContextFlags : 0x1003f
+0x004 Dr0 : 0
+0x008 Dr1 : 0
+0x00c Dr2 : 0
+0x010 Dr3 : 0
+0x014 Dr6 : 0
+0x018 Dr7 : 0
+0x01c FloatSave : _FLOATING_SAVE_AREA
+0x08c SegGs : 0
+0x090 SegFs : 0x3b
+0x094 SegEs : 0x23
+0x098 SegDs : 0x23
+0x09c Edi : 1
+0x0a0 Esi : 0x2b13178
+0x0a4 Ebx : 0x2b12fd0
+0x0a8 Edx : 0
+0x0ac Ecx : 3
+0x0b0 Eax : 0x23e1ec
+0x0b4 Ebp : 0x23e23c
+0x0b8 Eip : 0x7521b760
+0x0bc SegCs : 0x1b
+0x0c0 EFlags : 0x202
+0x0c4 Esp : 0x23e1ec
+0x0c8 SegSs : 0x23
+0x0cc ExtendedRegisters : [512] "???"
您甚至可以通过使用 .extptr 获得两者(注意您可能需要在使用此命令后使用 .cxr 将上下文重置为默认范围)
0:000> .exptr (@esp+4)
----- Exception record at 0023dee8:
ExceptionAddress: 7521b760 (KERNELBASE!RaiseException+0x00000058)
ExceptionCode: e06d7363 (C++ EH exception)
ExceptionFlags: 00000001
NumberParameters: 3
Parameter[0]: 19930520
Parameter[1]: 0023e294
Parameter[2]: 007c15b4
unable to find C-Runtime symbols, even with unqualified search
----- Context record at 0023df08:
eax=0023e1ec ebx=02b12fd0 ecx=00000003 edx=00000000 esi=02b13178 edi=00000001
eip=7521b760 esp=0023e1ec ebp=0023e23c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
KERNELBASE!RaiseException+0x58:
7521b760 c9 leave
0:000> kb 3
# ChildEBP RetAddr Args to Child
00 0023e23c 7579359c e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58
01 0023e274 0079eee0 0023e294 007c15b4 02b13178 msvcrt!_CxxThrowException+0x48
02 0023e288 0079146e 02b13178 80000002 c87a3f02 calc!divrat+0x69
0:000> .cxr
Resetting default scope
0:000> kb 3
# ChildEBP RetAddr Args to Child
00 0023ded0 76e77057 0023dee8 0023df08 0023dee8 ntdll!RtlDispatchException
01 0023ded0 7521b760 0023dee8 0023df08 0023dee8 ntdll!KiUserExceptionDispatcher+0xf
02 0023e23c 7579359c e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58
希望这足以让你自己研究你不能泄露实际 windbg 堆栈跟踪的具体情况
所以,我在我正在查看的转储 (x86/Windows 7) 的调用堆栈之一中看到了这一行。由于我的问题仅与此电话有关,因此我已将其大量删除。
Args to Child
01111111 04444444 05555555 ntdll!KiUserExceptionDispatcher+0xf
经过:http://www.nynaeve.net/Code/KiUserExceptionDispatcher.c
看起来堆栈上的前两个参数必须是上下文记录和异常记录。然而,通过一些实验,我注意到 01111111
不是第一个参数。它实际上是从 04444444
开始的。因此,在这种情况下 .cxr 04444444
和 .exr 05555555
显示正常的输出。
现在,我知道调试器可能只显示此时堆栈上的任何内容,我可能不应该单独依赖它,但是如果下面那一行都被标记了使用 "stack unwind information not available. Following frames may be wrong",我怎么知道我应该忽略 01111111?
更新
让我们试试不同的方法。以下是 2 条相关信息:
Args to Child
0ccccccc 77895ac4 00000000 kernel32!UnhandledExceptionFilter+0x9e
[... various other calls here, leading up to ...]
0eeeeeee 0aaaaaaa 0bbbbbbb ntdll!KiUserExceptionDispatcher+0xf
所以,检查一下。 UnhandledExceptionFilter
的唯一参数是一个 EXCEPTION_POINTERS* 结构,对吗?
0:010> dd 0ccccccc l2
0ddddddd 0bbbbbbb 0aaaaaaa
在 EXCEPTION_POINTERS 结构中,第一个字段是 EXCEPTION_RECORD (0bbbbbbb),而第二个字段是 CONTEXT_RECORD (0aaaaaaa)。然而,在对 KiUserEceptionDispatcher 的调用中,这些参数以相反的方式出现。更不用说 0eeeeeee NOT 是 KiUserExceptionDispatcher 的第一个参数,但 0ccccccc IS 是 UnhandledExceptionFilter 的第一个参数。
我很困惑!
windows 7 x86 32位机
winkey + r -> windbg 计算
bp ntdll!KiUserExceptionDispatcher
f5
在计算器中除以 0/0 以引发异常
(ac8.c8c): C++ EH exception - code e06d7363 (first chance)
Breakpoint 0 hit
eax=0023e1ec ebx=02b12fd0 ecx=00000003 edx=00000000 esi=02b13178 edi=00000001
eip=76e77048 esp=0023dee0 ebp=0023e23c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!KiUserExceptionDispatcher:
76e77048 fc cld
你的 post 显示 return 地址为 + 0xf 所以让我们看看到那一点
0:000> u . .+f
ntdll!KiUserExceptionDispatcher:
76e77048 fc cld
76e77049 8b4c2404 mov ecx,dword ptr [esp+4]
76e7704d 8b1c24 mov ebx,dword ptr [esp]
76e77050 51 push ecx
76e77051 53 push ebx
76e77052 e85d88fdff call ntdll!RtlDispatchException (76e4f8b4)
76e77057 0ac0 or al,al
看来您在从调用堆栈中输入 RtlDispatchException 后出现故障
打破进入通话
0:000> tc
eax=0023e1ec ebx=0023dee8 ecx=0023df08 edx=00000000 esi=02b13178 edi=00000001
eip=76e77052 esp=0023ded8 ebp=0023e23c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!KiUserExceptionDispatcher+0xa:
76e77052 e85d88fdff call ntdll!RtlDispatchException (76e4f8b4)
0:000> t
eax=0023e1ec ebx=0023dee8 ecx=0023df08 edx=00000000 esi=02b13178 edi=00000001
eip=76e4f8b4 esp=0023ded4 ebp=0023e23c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!RtlDispatchException:
76e4f8b4 8bff mov edi,edi
查看堆栈,如果您要求 windbg 冗长,它甚至会为您破译上下文
0:000> kb 3
# ChildEBP RetAddr Args to Child
00 0023ded0 76e77057 0023dee8 0023df08 0023dee8 ntdll!RtlDispatchException
01 0023ded0 7521b760 0023dee8 0023df08 0023dee8 ntdll!KiUserExceptionDispatcher+0xf
02 0023e23c 7579359c e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58
0:000> kv 3
# ChildEBP RetAddr Args to Child
00 0023ded0 76e77057 0023dee8 0023df08 0023dee8 ntdll!RtlDispatchException (FPO: [Non-Fpo])
01 0023ded0 7521b760 0023dee8 0023df08 0023dee8 ntdll!KiUserExceptionDispatcher+0xf (FPO: [2,0,0]) (CONTEXT @ 0023df08)
02 0023e23c 7579359c e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58 (FPO: [Non-Fpo])
exr 输出
0:000> .exr poi(@esp+4)
ExceptionAddress: 7521b760 (KERNELBASE!RaiseException+0x00000058)
ExceptionCode: e06d7363 (C++ EH exception)
ExceptionFlags: 00000001
NumberParameters: 3
Parameter[0]: 19930520
Parameter[1]: 0023e294
Parameter[2]: 007c15b4
unable to find C-Runtime symbols, even with unqualified search
上下文记录输出
0:000> dt ntdll!_CONTEXT poi(@esp+8)
+0x000 ContextFlags : 0x1003f
+0x004 Dr0 : 0
+0x008 Dr1 : 0
+0x00c Dr2 : 0
+0x010 Dr3 : 0
+0x014 Dr6 : 0
+0x018 Dr7 : 0
+0x01c FloatSave : _FLOATING_SAVE_AREA
+0x08c SegGs : 0
+0x090 SegFs : 0x3b
+0x094 SegEs : 0x23
+0x098 SegDs : 0x23
+0x09c Edi : 1
+0x0a0 Esi : 0x2b13178
+0x0a4 Ebx : 0x2b12fd0
+0x0a8 Edx : 0
+0x0ac Ecx : 3
+0x0b0 Eax : 0x23e1ec
+0x0b4 Ebp : 0x23e23c
+0x0b8 Eip : 0x7521b760
+0x0bc SegCs : 0x1b
+0x0c0 EFlags : 0x202
+0x0c4 Esp : 0x23e1ec
+0x0c8 SegSs : 0x23
+0x0cc ExtendedRegisters : [512] "???"
您甚至可以通过使用 .extptr 获得两者(注意您可能需要在使用此命令后使用 .cxr 将上下文重置为默认范围)
0:000> .exptr (@esp+4)
----- Exception record at 0023dee8:
ExceptionAddress: 7521b760 (KERNELBASE!RaiseException+0x00000058)
ExceptionCode: e06d7363 (C++ EH exception)
ExceptionFlags: 00000001
NumberParameters: 3
Parameter[0]: 19930520
Parameter[1]: 0023e294
Parameter[2]: 007c15b4
unable to find C-Runtime symbols, even with unqualified search
----- Context record at 0023df08:
eax=0023e1ec ebx=02b12fd0 ecx=00000003 edx=00000000 esi=02b13178 edi=00000001
eip=7521b760 esp=0023e1ec ebp=0023e23c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
KERNELBASE!RaiseException+0x58:
7521b760 c9 leave
0:000> kb 3
# ChildEBP RetAddr Args to Child
00 0023e23c 7579359c e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58
01 0023e274 0079eee0 0023e294 007c15b4 02b13178 msvcrt!_CxxThrowException+0x48
02 0023e288 0079146e 02b13178 80000002 c87a3f02 calc!divrat+0x69
0:000> .cxr
Resetting default scope
0:000> kb 3
# ChildEBP RetAddr Args to Child
00 0023ded0 76e77057 0023dee8 0023df08 0023dee8 ntdll!RtlDispatchException
01 0023ded0 7521b760 0023dee8 0023df08 0023dee8 ntdll!KiUserExceptionDispatcher+0xf
02 0023e23c 7579359c e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58
希望这足以让你自己研究你不能泄露实际 windbg 堆栈跟踪的具体情况