【问题标题】:WinDbg not showing entire call stack?WinDbg 没有显示整个调用堆栈?
【发布时间】:2018-03-18 01:41:36
【问题描述】:

我正在尝试使用 WinDbg 调试一个名为“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 是主 UI 线程,它在对话框创建时被冻结。但是,调用堆栈中记录的最底部函数是DlgBox!Ordinal49,它位于由可执行文件加载的DlgBox.dll 中。

显然这不是完整的调用堆栈,因为这是主线程,因此可执行文件中的main() 方法无法退出/返回,否则进程将关闭。

那么为什么调用堆栈以 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

【问题讨论】:

  • 但是如果 pdb 文件(带有帧信息)不适用于堆栈中的所有模块 - 在 x86 中不可能总是获得完整的堆栈跟踪。调试器假定该函数使用 ebp 帧(push ebp;mov ebp,esp at begin)并通过这个 ebp 链。但是如果某些函数没有使用这个框架 - 这里堆栈跟踪可以停止。
  • 啊,有没有办法尝试不同的帧类型?

标签: windows debugging windbg callstack


【解决方案1】:

.kframes <FrameCountDefault>:

.kframes 命令设置堆栈跟踪显示的默认长度。

[...]

如果您从不发出 .kframes 命令,则默认计数为 20 (0x14)。

如果您使用k 命令,您还可以指定长度,例如k Lfff

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    相关资源
    最近更新 更多