我的系统上安装了二进制文件,并希望查看给定函数的反汇编.优选使用objdump
,但其他解决方案也是可以接受的.
从这些问题我已经了解到,如果我只知道边界地址,我可能能够反汇编部分代码.从这个答案我已经学会了如何将我的拆分调试符号转换回单个文件.
但即使在单个文件上运行,甚至反汇编所有代码(即没有启动或停止地址,但只是简单的-d
参数objdump
),我仍然没有在任何地方看到该符号.这是有道理的,因为有问题的函数是静态的,所以它不会被导出.然而,valgrind
将报告函数名称,因此它必须存储在某处.
查看调试部分的详细信息,我找到了本.debug_str
节中提到的名称,但我不知道可以将其转换为地址范围的工具.
我想解释一下GCC生成的汇编中.cfi_def_cfa_offset指令使用的值.我隐约知道.cfi指令涉及调用帧和堆栈展开,但我想更详细地解释为什么,例如,在编译以下C程序时GCC输出的汇编中使用值16和8的原因在我的64位Ubuntu机器上.
C程序:
#include <stdio.h>
int main(int argc, char** argv)
{
printf("%d", 0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在源文件test.c上调用了GCC,如下所示:gcc -S -O3 test.c
.我知道-O3可以实现非标准优化,但为了简洁起见,我想限制生成的程序集的大小.
生成的程序集:
.file "test.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB22:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
xorl %edx, %edx
movl $.LC0, %esi
movl $1, %edi
xorl %eax, %eax
call __printf_chk
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE22:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
.section .note.GNU-stack,"",@progbits …
Run Code Online (Sandbox Code Playgroud) 共享对象是在RedHat Linux上构建的,虽然所有代码都是使用debug编译的,但调试器(gdb)拒绝加载符号并发出错误,如下所示:
...
GNU gdb Fedora (6.8-37.el5)
...
This GDB was configured as "x86_64-redhat-linux-gnu"...
Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module libgrokf.so]
Run Code Online (Sandbox Code Playgroud)
有了这个错误,我无法在任何函数中触发断点,也看不到正确的堆栈跟踪.我重新编译了整个项目,但没有任何帮助.我知道在过去的某个时间调试该模块没有问题.
是什么导致了这个问题?
有关良好的跨平台库的任何建议,以读取DWARF格式的ELF文件调试信息?我想在Python程序中阅读DWARF调试信息.
GCC 4.8支持DWARF4.我想知道从用户的角度来看DWARF4和DWARF2之间有什么区别.
让我们从GDB的角度来看待它.切换到DWARF4时,用户有什么不同吗?
我找到了一个矮人主页,但据我所知,网上没有关于用户POV差异的信息.
你能指出那些差异吗?
寻找在我的二进制文件(准确地说.so
)中查看特定函数的生成汇编程序的方法,就像我在Compiler Explorer上看到类似的那样,我发现了How to disassemble one single function using objdump? 并根据那里的答案(以及我的进一步搜索)我最终使用了以下命令:
objdump --wide --no-address --no-show-raw-insn [--demangle] --disassemble="<symbol>" -- "<binary>"
Run Code Online (Sandbox Code Playgroud)
<symbol>
我发现使用的地方:
objdump --syms [--demangle] -- "<binary>" | grep <function>
Run Code Online (Sandbox Code Playgroud)
其中,the 又<function>
是我感兴趣的 C++ 函数名称。当然,the<symbol>
是一个损坏的名称。(为了完整起见,我得到了两个结果 - 一个是预期的结果,另一个是带.cold
后缀的结果,由“主结果”使用。)
结果已经很扎实了。然而,浏览objdump
选项后我看到了有希望的选项:
-C
/ --demangle
,-l
/ --line-numbers
,-S
/ --source
。但是,我无法让他们工作......
INITIAL:第一个 ( -C
/ --demangle
) 导致根本不打印任何反汇编代码。如果没有它,在该Disassembly of section .text:
行之后我会有一行带有符号的行,后跟反汇编。使用此选项时,不会显示符号和反汇编,而是Disassembly of section .fini: …
我正在使用 Crashlytics 来报告 iOS 应用程序中发生的崩溃。在这里,我想知道如何在xcode中找到这些dwarf文件夹和文件下面的路径:
DWARF_DSYM_FOLDER_PATH
DWARF_DSYM_FILE_NAME
我正在研究一个实用程序,它需要将十六进制地址解析为二进制内的符号函数名和源代码行号.该实用程序将在x86上的Linux上运行,但它分析的二进制文件将用于基于MIPS的嵌入式系统.MIPS二进制文件采用ELF格式,使用DWARF作为符号调试信息.
我目前正计划派生objdump,传入十六进制地址列表并解析输出以获取函数名称和源行号.我已经编译了一个支持MIPS二进制文件的objdump,它正在工作.
我更喜欢有一个软件包,允许我从Python代码本地查找内容而不需要另外的进程.我在python.org上找不到libdwarf,libelf或libbfd,也没有提到dwarfstd.org上的python.
某处有合适的模块吗?
Apple GCC在哪里/如何将DWARF存储在可执行文件中?
我编译了一个二进制文件gcc -gdwarf-2
(Apples GCC).但是,既没有objdump -g
也objdump -h
没有向我显示任何调试信息.
libbfd也找不到任何调试信息.(我在binutils-mailinglist上问过这个问题.)
然而,我能够通过dsymutil
(进入dSYM)提取调试信息.libbfd也可以读取那些调试信息.