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

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

假设我有类似以下的内容

int main() { caller_f1() { f1(); // breakpoint f2() } // want to skip f2() and jump caller_f2() { // jump to this this location ?? f1(); f2(); } } 

似乎有一个跳转命令正是您正在寻找的:

http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html#SEC163

更新链接: http ://web.archive.org/web/20140101193811/http: //idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html#SEC163

要在新地址处继续执行,请使用jump (短格式: j ):

 jump LINENUM jump *ADDRESS 

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

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

请参阅@ gospes关于相关问题的答案 ,以获得一个方便的skip宏。


在非优化代码( -O0 )中使用jump只是“安全” ,即使只在当前函数中使用。 它只修改程序计数器; 它不会改变任何其他寄存器或内存。

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

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

gcc的手册建议在通常的编辑 – 编译 – 调试周期中使用-Og ,但即使是那种轻量级的优化也会破坏变量的jump和异步修改。 如果您不想在调试时这样做,那么这是一个不错的选择,特别是对于-O0运行速度太慢以至于出现问题的项目。


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

 set $pc = 0x4005a5 

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

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

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