GDB:为什么不使用-g进行编译时为什么不能执行单个语句?

时间:2019-08-24 19:51:44

标签: c debugging gdb

我正在探讨使用-g选项和不使用-g选项编译的可执行文件的gdb行为差异。

所以,我观察到以下我不理解的东西:

1。我无法在代码的一行上放置断点。每次尝试时,它将放置在文件../sysdeps/x86_64/start.S,第63行中 Here's the image of what I see when I try to place breakpoint on line number 34 in my program

2。但是,我可以使用函数名称放置断点。所以我在主程序的开头放置了断点。但是之后,我无法进入程序的下一行。键入“ next”后,执行将到达程序末尾。为什么会这样?这是预期的行为吗?是因为没有行号信息? Image for this case

注意:由于这是我的第一个问题,我无法发布图像,因此发布到图像的链接。很抱歉。

我了解为什么在放置断点时行号不可见或程序名称不可见,以及“信息本地人”为什么不显示符号。 另外,我了解到,当我不使用-g时,调试信息不​​会以DWARF格式存储,但我是否仍应能够调试代码?我不明白为什么我不能逐行遍历代码或放置断点。

我检查了类似的问题,但他们没有提及我观察到的行为。 this this

我的主要功能如下:

main(){
 printf("Starting to build the linked list\n");
 .
 .
 .
 printf("Printing values of the list");
}

这些是预期的行为还是我错过了一些东西?是否有关于不带-g的gdb行为的文档?

2 个答案:

答案 0 :(得分:1)

-g要做的一件事是保存一条记录,以记录源文件中哪些行和语句与已编译程序中的哪些机器语言指令相对应。没有这些信息,调试器将无法基于源行语句放置断点,并且也无法逐行执行,这也是因为它不知道行/语句边界在哪里。

您仍然可以在函数的开始处设置断点,因为如今,符号表(除其他事项外,它指示每个函数在机器代码中的位置)被认为是非常基本的,即使没有-g,它通常也被包括在内。

答案 1 :(得分:1)

在没有-g的情况下,调试器没有行号信息,因此它不知道哪些指令对应于源文件的哪一行。因此,使用nextstep等效于continue -它们将运行。

您可以做的是使用nextistepi命令(缩写为nisi)。这些命令执行一条机器指令,并在下一条指令处停止。不幸的是,在这些情况下,gdb不会逐步输出有用的机器指令信息,但是您可以在.gdbinit文件中放入以下内容:

define sx
  si
  x /1i $pc
end
document sx
    Step one instruction and print next instruction
end
define nx
  ni
  x /1i $pc
end
document nx
    Step one instruction running through calls and print next instruction
end

这些命令(nxsxnisi的更有用的版本-单步执行一条指令,然后分解下一条要运行的指令

对于断点问题,可以使用例如
break *0x4000fed将断点放在特定的机器指令上,但是您需要知道特定的原始地址。您可以使用
disassemble start来在特定符号处反汇编代码,以查看具有该功能的指令的原始地址。