要在新地址恢复执行,请使用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 调试技巧。)