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

2023-11-29

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

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

int main()
{
  caller_f1() {  

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

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

要在新地址恢复执行,请使用jump(简写:j):

jump LINENUM
jump *ADDRESS

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

linenum 可以是任何linespec表达方式,如+1对于下一行。

See @gospes 的回答在一个相关的问题上方便skip宏正是这样做的。


Using jump仅在未优化的代码中“安全”(-O0),甚至仅在当前函数内。它only修改程序计数器;它不会更改任何其他寄存器或内存。

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

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

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


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

set $pc = 0x4005a5

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

这相当于tbreak + jump,但不能使用行号,只能使用指令地址。 (并且您不会收到跳出当前函数的警告+确认请求)。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以在 GDB 调试器中“跳转”/“跳过”? 的相关文章

随机推荐