是否可以在GDB调试器中“跳转”/“跳过”?

时间:2010-11-07 05:34:56

标签: c debugging gdb

在GDB中调试时是否可以跳转到代码/可执行文件中的某个位置/地址?

假设我有类似于以下内容的内容

int main()
{
  caller_f1() {  

   f1();  // breakpoint  
   f2() } // want to skip f2() and jump 

  caller_f2() { // jump to this this location ??       
   f1();  
   f2(); }  
}

2 个答案:

答案 0 :(得分:7)

答案 1 :(得分:6)

要在新地址继续执行,请使用jump(简称:j):

jump LINENUM
jump *ADDRESS

The GDB manual建议在跳跃之前使用tbreak(临时断点)。

亚麻布可以是任何linespec表达式,例如下一行的+1

有关方便skip宏的相关问题,请参阅@gospes's answer

使用jump只是"安全"在未优化的代码(-O0中,甚至只在当前函数中。 修改程序计数器;它不会改变任何其他寄存器或存储器。

只有gcc -O0将每个源语句(或行?)编译成一个独立的指令块,从内存加载变量值并存储结果。这允许您在任何断点处使用调试器修改变量值,并使机器代码中的行之间的jump工作,就像在C源代码行之间跳转一样。

这是-O0制作如此慢代码的部分原因:不仅编译器不花时间优化,还需要制作慢速代码,在每个语句之后溢出/重新加载所有内容以支持异步修改变量和甚至程序计数器。 (在典型的x86上,存储/重新加载延迟大约是5个周期,因此在add版本中,1个周期-O0需要6个周期。

对于通常的编辑 - 编译 - 调试循环,

gcc's manual suggests using -Og,但即使是那种轻量级的优化也会破坏jump和变量的异步修改。如果您不希望在调试时这样做,那么这是一个不错的选择,特别是对于-O0运行速度太慢以至于出现问题的项目。

要将程序计数器/指令指针设置为新地址而不恢复,您也可以使用:

set $pc = 0x4005a5

从反汇编窗口(layout asm / layout reg)复制/粘贴地址。

这相当于tbreak + jump,但您不能使用行号,只能使用指令地址。 (并且你没有得到警告+确认请求跳出当前功能)。

然后你可以stepi从那里开始。 $pc是一个通用的gdb名称,用于在目标体系结构中真正调用寄存器。例如RIP在x86-64中。 (另请参阅标记wiki的底部,了解gdb的asm调试技巧。)