C结构的内存布局可视化
Visualisation of the memory layout of C structs
我目前正在开发一个与其他汇编代码有大量接口的 C 项目。我们正在使用我们正在使用的控制块和结构的自制可视化,我正在锁定一个关于如何自动化这个过程的过程。
由于每个汇编控制块都有一个 C 结构等效项,并且我们正在为一种非常罕见的体系结构编程,因此最简单的方法可能是可视化 C 结构。
我或多或少正在寻找一种方法来自动获取 TCP wiki 页面中的 "TCP pseudo-header for checksum computation (IPv6)" 之类的图表:
TCP pseudo-header for checksum computation (IPv6)
遗憾的是,我还没有找到任何能够从 C 头文件生成此类可视化效果的开源工具。有没有办法在不手动编写的情况下生成此类图像或 html 表示?
编辑:感谢 Alexey Frunze 的想法,使用实用程序 pahole 可以从目标文件的 DWARF 部分提取所有使用的结构的真实内存布局。
其中一种方法是使用这些结构编译 C 代码,并从 object/executable 文件的调试信息中提取结构信息。否则,您正在研究 finding/making 结构解析器或 hacking clang。
UPD: 没试过,但是有 pycparser,可能有用。
某些 C 集合(struct
、union
、数组)的布局是 实现 特定的,因为 data structure alignment constraints (required by your particular ABI)。
您可能会使用调试器(例如 gdb
的 ptype
命令)。请注意 ddd
有一个图形显示。
如果您有许多 个结构,您可以考虑自定义您的GCC compiler using MELT。您将开发特定的 MELT 扩展来显示布局。这可能需要数周时间(因为您需要了解一些 GCC 内部结构)。
我正在开发一个 C 工具箱,除其他外,它可以绘制任何复杂度的 C 类型图。它在使用“-g”编译的代码中导入和理解 Dwarf 信息,并可以以 "dot" 格式转储任何你想要的信息(可以通过任意数量的工具显示。)
(这也是一种编程语言,它使用这种 Dwarf 理解能力直接访问 library/program 内部结构,在 运行 时不需要零胶水代码或 linking。)
参见:https://github.com/jasonnyberg/j2/wiki/Diagramming-C-types-using-j2
j2系统可以读取和理解矮人信息;作为调试功能,它还可以以 "dot" 语言的形式转储您 select 的项目,这允许以图形形式显示类型信息层次结构。 "stack" 函数显示解释器堆栈顶层的项目,也将这些项目转储到 /tmp/VMRES_STACK.dot.
要绘制一个项目,所需要做的就是按名称引用它(如果它不在堆栈中),然后使用 "stack!" 调用堆栈函数(它引用函数 "stack" 按名称,然后通过“!”运算符对其求值。)
一旦你有了解释器 运行ning(请参阅上面的 link 以了解解释器本身和一个转储结构图的实际示例 运行),你只需要A) "import" 图书馆:
j2> loadlib([test/build/libtestlib.so]) @testlib
然后 B) 引用您导入的结构(将其添加到解释器的堆栈):
j2> testlib.teststruct
最后,C) 显示堆栈(以文本方式,作为副作用,生成文件 /tmp/VMRES_STACK.dot):
j2> stack!
/tmp/VMRES_STACK.dot 中包含的图表可以通过许多 graphviz/dot 查看器中的任何一个显示,例如 xdot:
bash> xdot /tmp/VMRES_STACK.dot
xdot /tmp/VMRES_STACK.dot
我目前正在开发一个与其他汇编代码有大量接口的 C 项目。我们正在使用我们正在使用的控制块和结构的自制可视化,我正在锁定一个关于如何自动化这个过程的过程。
由于每个汇编控制块都有一个 C 结构等效项,并且我们正在为一种非常罕见的体系结构编程,因此最简单的方法可能是可视化 C 结构。
我或多或少正在寻找一种方法来自动获取 TCP wiki 页面中的 "TCP pseudo-header for checksum computation (IPv6)" 之类的图表:
TCP pseudo-header for checksum computation (IPv6)
遗憾的是,我还没有找到任何能够从 C 头文件生成此类可视化效果的开源工具。有没有办法在不手动编写的情况下生成此类图像或 html 表示?
编辑:感谢 Alexey Frunze 的想法,使用实用程序 pahole 可以从目标文件的 DWARF 部分提取所有使用的结构的真实内存布局。
其中一种方法是使用这些结构编译 C 代码,并从 object/executable 文件的调试信息中提取结构信息。否则,您正在研究 finding/making 结构解析器或 hacking clang。
UPD: 没试过,但是有 pycparser,可能有用。
某些 C 集合(struct
、union
、数组)的布局是 实现 特定的,因为 data structure alignment constraints (required by your particular ABI)。
您可能会使用调试器(例如 gdb
的 ptype
命令)。请注意 ddd
有一个图形显示。
如果您有许多 个结构,您可以考虑自定义您的GCC compiler using MELT。您将开发特定的 MELT 扩展来显示布局。这可能需要数周时间(因为您需要了解一些 GCC 内部结构)。
我正在开发一个 C 工具箱,除其他外,它可以绘制任何复杂度的 C 类型图。它在使用“-g”编译的代码中导入和理解 Dwarf 信息,并可以以 "dot" 格式转储任何你想要的信息(可以通过任意数量的工具显示。)
(这也是一种编程语言,它使用这种 Dwarf 理解能力直接访问 library/program 内部结构,在 运行 时不需要零胶水代码或 linking。)
参见:https://github.com/jasonnyberg/j2/wiki/Diagramming-C-types-using-j2
j2系统可以读取和理解矮人信息;作为调试功能,它还可以以 "dot" 语言的形式转储您 select 的项目,这允许以图形形式显示类型信息层次结构。 "stack" 函数显示解释器堆栈顶层的项目,也将这些项目转储到 /tmp/VMRES_STACK.dot.
要绘制一个项目,所需要做的就是按名称引用它(如果它不在堆栈中),然后使用 "stack!" 调用堆栈函数(它引用函数 "stack" 按名称,然后通过“!”运算符对其求值。)
一旦你有了解释器 运行ning(请参阅上面的 link 以了解解释器本身和一个转储结构图的实际示例 运行),你只需要A) "import" 图书馆:
j2> loadlib([test/build/libtestlib.so]) @testlib
然后 B) 引用您导入的结构(将其添加到解释器的堆栈):
j2> testlib.teststruct
最后,C) 显示堆栈(以文本方式,作为副作用,生成文件 /tmp/VMRES_STACK.dot):
j2> stack!
/tmp/VMRES_STACK.dot 中包含的图表可以通过许多 graphviz/dot 查看器中的任何一个显示,例如 xdot:
bash> xdot /tmp/VMRES_STACK.dot
xdot /tmp/VMRES_STACK.dot