给定结构体字段的偏移量,确定该字段所在的结构体字段。

5
假设我正在调试优化的代码中的一个崩溃。我查看反汇编并看到类似以下内容:
lea eax,[edi+8Ch] 

现在假设我知道存储在edi中的结构,并且在这种情况下,它是一个相当大的结构。足够大,以至于我不能一眼看出8Ch偏移对应哪个字段。
我一直在做的就是在Visual Studio的监视窗口中打开并手动执行指针算术运算(offsetof宏将执行此操作),直到找到匹配的那个,但这很繁琐。有没有更快速地确定正在访问哪个字段的方法?

你读取反汇编来调试C程序有充分的理由吗? - Mike Kwan
由于许多函数被内联,调用堆栈无法准确反映我所在的函数(而且崩溃本身发生在一个内联函数中),因此我需要查看反汇编以确定崩溃实际发生的位置。 - Alex
这段代码不能在调试模式下进行调试吗? - Mike Kwan
这是我收到的崩溃转储,不是本地发生的事情。我想我可以尝试重现它,但有时候能够快速地查看转储并了解正在发生的情况比重现崩溃发生的条件更快捷和方便。 - Alex
1
cl.exe input.cpp /d1reportAllClassLayout > layouts.txt 将生成所有类/结构的布局转储。不幸的是,似乎需要编译为 C++,而不是纯 C(添加 /TP 强制将 .c 文件编译为 C++)。 - DCoder
1
@DCoder 非常好,但并非所有的C代码都是C++代码,因此将其编译起来可能需要很多工作。 - Alexey Frunze
2个回答

4
在Visual Studio中,您应该能够像这样“监视”表达式:
(unsigned)&(((StructTypeName*)0)->StructFieldName)

你可以输入不同的字段名,直到VS显示出正确的偏移值。

你也可以将你的应用程序加载到WinDbg中(确保符号已加载),并使用dt命令。WinDbg将转储所提供类型/变量名称的布局/内容,并显示所有字段的偏移量。


对于第一个建议,我在初始问题中已经发布了我当前所做的事情,但是在大型结构体中手动进行二分查找所有字段变得很繁琐。我将会查看WinDbg并看看dt是否符合我的要求。 - Alex

0
如果你需要花时间进行调试,我建议编写一个程序,打印出所有结构体字段的偏移量,并将它们列在“偏移量;字段”对中。
我会更进一步地编写一个脚本(例如使用 Python),它获取结构体的文本并生成一个包含所有结构体字段的offsetof语句的 C 代码文件。

1
这似乎可以工作,但是会很麻烦 - 我必须让我的脚本解析整个程序,以处理嵌入式结构或typedef的情况,并了解如何打包和对齐。正确地执行并可靠地处理所有边缘情况将会很麻烦。 - Alex
1
如果您将代码编译为C ++,MSVC可以提供此信息。是的,我知道在某些情况下可能不是一个选项。 - DCoder
是的,在这种情况下肯定行不通。这段代码与C++不兼容。:-/ - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接