是否可以在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调试技巧。)