基本上,据我所知,
如果我们使用GDB来调试从C源代码编译的执行代码, 编译器会将源代码路径保留在ELF/PE文件中,因此 GDB将使用源代码来促进我们的调试过程。
但是GDB如何在上述过程中提供asm代码信息呢?我给出一个在我的计算机上捕获的示例,如下所示:
所以我的问题是:
- GDB如何提供asm代码?这是反汇编生成的asm代码吗?
- 如果是这样,那么GDB如何保证反汇编的准确性呢? 据我所知,使用像OBJDUMP这样的线性反汇编算法无法区分数据和代码,像IDA pro这样的商业工具也会时不时地出错
有人可以给我一些帮助吗?谢谢!
最佳答案
请记住,“编译器”(例如 gcc )会执行以下几项操作:
- 预处理(#includes、宏等)
- 正确编译(将预处理的 c 转换为汇编)
- 程序集(将程序集转换为目标代码)
- 链接(将对象适当打包到库/可执行文件中)
到目前为止,最复杂的部分是编译阶段。
还请记住,汇编或多或少是目标代码中包含的机器指令的直接表示。
那么,回答你的问题:
- GDB 读取您的库/可执行文件,并简单地(相对)提取机器指令,从而提取汇编代码。这就是反汇编过程。
- 同样,由于 GDB 直接从库/可执行文件获取机器指令/目标代码,只要它能够准确地将机器代码转换为汇编指令,提供准确的反汇编就不会有太大问题。里>
换句话说,从源代码到汇编是一对一的映射,这意味着对于给定的源代码,给定不同的编译器、编译器选项等,汇编代码有许多可能的排列。这意味着很难,如果不是不可能从纯目标代码派生源代码。因此,为了有效调试 C 源代码,源代码必须可供 GDB 使用,无论是嵌入的还是原始的 .c 形式。
相反,从汇编代码到目标代码更接近于 1:1 映射,因为两者或多或少代表同一事物 - 创建给定程序所需的内存中指令的布局。因此,反汇编过程比任何潜在的“反编译”过程要简单得多。
关于debugging - GDB中调试过程中的asm代码从何而来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20752656/