我正在尝试使用WinDbg来debugging一个名为“Ballmaster”(其源代码不具备)的非常古老的游戏。 当显示对话框时,我将WinDbg附加到游戏中,以便UI线程的调用堆栈不会更改。
以下是正在运行的线程列表:
当我点击Ballmaster
线程时,会出现下面的调用堆栈:
ntdll!NtDelayExecution + 0xc KERNELBASE!SleepEx + 0x99 KERNELBASE!Sleep + 0xf USER31!HookedCreateWindowExA + 0x41 DlgBox!Ordinal49 + 0x35dd DlgBox!Ordinal49 + 0x4d58 uxtheme!ThemePreDefDlgProc + 0x83 USER32!UserCallDlgProcCheckWow + 0x2a8 USER32!DefDlgProcWorker + 0xc7 USER32!DefDlgProcA + 0x25 USER32!_InternalCallWinProc + 0x2b USER32!UserCallWinProcCheckWow + 0x2d3 USER32!SendMessageWorker + 0x26c USER32!InternalCreateDialog + 0xb07 USER32!CreateDialogIndirectParamAorW + 0x35 USER32!CreateDialogIndirectParamA + 0x1b DlgBox!Ordinal49 + 0x52bf
Ballmaster
是主要的用户界面线程,它在创build对话框时被冻结。 但是,调用堆栈中logging的最底层函数是DlgBox!Ordinal49
,它位于DlgBox.dll
,由可执行文件加载。
很明显,这不是完整的调用堆栈,因为这是主线程,可执行文件中的main()
方法不能退出/返回,否则进程将closures。
那么为什么调用堆栈以DLL中的函数而不是主可执行文件中的函数结束呢? 如何查看完整的调用堆栈?
!address DlgBox!Ordinal49+0x52bf
提供以下内容:
Usage: Image Base Address: 028e1000 End Address: 028f2000 Region Size: 00011000 ( 68.000 kB) State: 00001000 MEM_COMMIT Protect: 00000020 PAGE_EXECUTE_READ Type: 01000000 MEM_IMAGE Allocation Base: 028e0000 Allocation Protect: 00000080 PAGE_EXECUTE_WRITECOPY Image Path: C:\Users\mathu\Desktop\Games\Ballmaster\CrtC0B.tmp\DlgBox.DLL Module Name: DlgBox Loaded Image Name: C:\Users\mathu\Desktop\Games\Ballmaster\CrtC0B.tmp\DlgBox.DLL Mapped Image Name: More info: lmv m DlgBox More info: !lmi DlgBox More info: ln 0x28e52bf More info: !dh 0x28e0000
.kframes <FrameCountDefault>
:
.kframes命令设置堆栈跟踪显示的默认长度。
[…]
如果您从不发出.kframes命令,则默认计数为20(0x14)。
如果使用k
命令,还可以指定长度,例如k Lfff