debugging - GDB中调试过程中的asm代码从何而来?

标签 debugging assembly compiler-construction gdb disassembly

基本上,据我所知,

如果我们使用GDB来调试从C源代码编译的执行代码, 编译器会将源代码路径保留在ELF/PE文件中,因此 GDB将使用源代码来促进我们的调试过程。

但是GDB如何在上述过程中提供asm代码信息呢?我给出一个在我的计算机上捕获的示例,如下所示:

enter image description here

所以我的问题是:

  1. GDB如何提供asm代码?这是反汇编生成的asm代码吗?
  2. 如果是这样,那么GDB如何保证反汇编的准确性呢? 据我所知,使用像OBJDUMP这样的线性反汇编算法无法区分数据和代码,像IDA pro这样的商业工具也会时不时地出错

有人可以给我一些帮助吗?谢谢!

最佳答案

请记住,“编译器”(例如 )会执行以下几项操作:

  • 预处理(#includes、宏等)
  • 正确编译(将预处理的 c 转换为汇编)
  • 程序集(将程序集转换为目标代码)
  • 链接(将对象适当打包到库/可执行文件中)

到目前为止,最复杂的部分是编译阶段。

还请记住,汇编或多或少是目标代码中包含的机器指令的直接表示。

那么,回答你的问题:

  1. GDB 读取您的库/可执行文件,并简单地(相对)提取机器指令,从而提取汇编代码。这就是反汇编过程。
  2. 同样,由于 GDB 直接从库/可执行文件获取机器指令/目标代码,只要它能够准确地将机器代码转换为汇编指令,提供准确的反汇编就不会有太大问题。

换句话说,从源代码到汇编是一对一的映射,这意味着对于给定的源代码,给定不同的编译器、编译器选项等,汇编代码有许多可能的排列。这意味着很难,如果不是不可能从纯目标代码派生源代码。因此,为了有效调试 C 源代码,源代码必须可供 GDB 使用,无论是嵌入的还是原始的 .c 形式。

相反,从汇编代码到目标代码更接近于 1:1 映射,因为两者或多或少代表同一事物 - 创建给定程序所需的内存中指令的布局。因此,反汇编过程比任何潜在的“反编译”过程要简单得多。

关于debugging - GDB中调试过程中的asm代码从何而来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20752656/

相关文章:

debugging - 空程序段错误

c - 无法理解以下宏

assembly - PIC/汇编,在寄存器之间复制和循环 10 位

objective-c - 编译一个简单的 Objective-C 程序

c# - Xamarin.iOS 未处理错误启动软调试器 :System. NotSupportedException

c# - VS Code 1.19.3 调试.net core 2 总是遇到 "Only 64-bit processes can be debugged"

debugging - 盲源步进的奥秘,或F#在大型源文件上的行为异常

performance - 在没有优化的情况下添加冗余分配可以加快代码的速度

c++ - 为什么 C++ 编译器不消除 new 返回的指针的空检查?

c++ - 为什么函数参数名称在 C++ 声明中不重要?