在GDB中调试时是否可以跳转到代码/可执行文件中的某个位置/地址?
假设我有类似以下的内容
int main()
{
caller_f1() {
f1(); // breakpoint
f2() } // want to skip f2() and jump
caller_f2() { // jump to this this location ??
f1();
f2(); }
}
Run Code Online (Sandbox Code Playgroud)
要继续在新地址执行,请使用jump
(简短形式:) j
:
jump LINENUM
jump *ADDRESS
Run Code Online (Sandbox Code Playgroud)
GDB手册建议tbreak
在跳跃之前使用(临时断点).
亚麻布可以是任何linespec
表达,就像+1
下一行一样.
请参阅@ gospes关于相关问题的答案,以获得一个方便的skip
宏.
jump
在非优化代码(-O0
)中使用只是"安全",即使只在当前函数中使用.它只是修改程序计数器; 它不会改变任何其他寄存器或内存.
只gcc -O0
将每个源语句(或行?)编译成一个独立的指令块,从内存加载变量值并存储结果.这允许您在任何断点处使用调试器修改变量值,并使jump
机器代码中的行之间的工作类似于在C源中的行之间跳转.
这就是为什么-O0
编写这么慢的代码的一部分:不仅编译器不花时间优化,还需要制作慢速代码,在每个语句之后溢出/重新加载所有内容,以支持异步修改变量甚至程序计数器.(在典型的x86上,存储/重载延迟大约为5个周期,因此1 add
个周期在-O0
构建中需要6个周期).
gcc的手册建议使用-Og
通常的编辑 - 编译 - 调试周期,但即使是那种轻量级的优化也会破坏jump
变量的异步修改.如果您不想在调试时这样做,那么这是一个不错的选择,特别是对于-O0
运行速度太慢以至于存在问题的项目.
要将程序计数器/指令指针设置为新地址而不恢复,您还可以使用:
set $pc = 0x4005a5
Run Code Online (Sandbox Code Playgroud)
从反汇编窗口(layout asm
/ layout reg
)复制/粘贴地址.
这相当于tbreak
+ jump
,但不能使用行号,只能使用指令地址.(并且你没有收到警告+确认请求跳过当前功能).
然后你可以stepi
从那里. $pc
是目标体系结构中实际调用的寄存器的通用gdb名称.例如,x86-64中的RIP.(有关gdb的asm调试技巧,另请参阅x86标记wiki 的底部.)
似乎有一个跳转命令正是您正在寻找的:
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