简体   繁体   English

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

[英]Is it possible to “jump”/“skip” in GDB debugger?

Is it possible to jump to some location/address in the code/executable while debugging in GDB ? 在GDB中调试时是否可以跳转到代码/可执行文件中的某个位置/地址?

Let say I have something similar to the following 假设我有类似以下的内容

int main()
{
  caller_f1() {  

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

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

There seems to be a jump command which is exactly what you are looking for: 似乎有一个跳转命令正是您正在寻找的:

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

Updated link: http://web.archive.org/web/20140101193811/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

To resume execution at a new address, use jump (short form: j ): 要在新地址继续执行,请使用jump (短格式: j ):

jump LINENUM
jump *ADDRESS

The GDB manual suggests using tbreak (temporary breakpoint) before jumping. GDB手册建议在跳跃之前使用tbreak (临时断点)。

The linenum can be any linespec expression, like +1 for the next line. 亚麻布可以是任何linespec表达式,例如下一行的+1

See @gospes's answer on a related question for a handy skip macro that does exactly that. 请参阅@ gospes关于相关问题的答案 ,以获得一个方便的skip宏。


Using jump is only "safe" in un-optimized code ( -O0 ) , and even then only within the current function. 在非优化代码( -O0 )中使用jump只是“安全” ,即使只在当前函数中使用。 It only modifies the program counter; 它只修改程序计数器; it doesn't change any other registers or memory. 它不会改变任何其他寄存器或内存。

Only gcc -O0 compiles each source statement (or line?) into an independent block of instructions that loads variable values from memory and stores results. 只有gcc -O0将每个源语句(或行?)编译成一个独立的指令块,从内存加载变量值并存储结果。 This lets you modify variable values with a debugger at any breakpoint, and makes jump ing between lines in the machine code work like jumping between lines in the C source. 这允许您在任何断点处使用调试器修改变量值,并使机器代码中的行之间的jump工作,如在C源中的行之间跳转。

This is part of why -O0 makes such slow code: not only does the compiler not spend time optimizing, it is required to make slow code that spills/reloads everything after every statement to support asynchronous modification of variables and even program-counter. 这是为什么-O0制作如此慢的代码的部分原因:编译器不仅不花时间优化,还需要制作慢速代码,在每个语句之后溢出/重新加载所有内容以支持异步修改变量甚至程序计数器。 (Store/reload latency is about 5 cycles on a typical x86, so a 1 cycle add takes 6 cycles in -O0 builds). (在典型的x86上,存储/重新加载延迟约为5个周期,因此在-O0版本中,1个周期的add需要6个周期)。

gcc's manual suggests using -Og for the usual edit-compile-debug cycle, but even that light level of optimization will break jump and async modification of variables. gcc的手册建议在通常的编辑 - 编译 - 调试周期中使用-Og ,但即使是那种轻量级的优化也会破坏变量的jump和异步修改。 If you don't want to do that while debugging, it's a good choice, especially for projects where -O0 runs so slowly that it's a problem. 如果您不想在调试时这样做,那么这是一个不错的选择,特别是对于-O0运行速度太慢以至于出现问题的项目。


To set program-counter / instruction-pointer to a new address without resuming , you can also use this: 要将程序计数器/指令指针设置为新地址而不恢复 ,您还可以使用:

set $pc = 0x4005a5

Copy/paste addresses from the disassembly window ( layout asm / layout reg ). 从反汇编窗口复制/粘贴地址( layout asm / layout reg )。

This is equivalent to tbreak + jump , but you can't use line numbers, only instruction addresses. 这相当于tbreak + jump ,但是你不能使用行号,只能使用指令地址。 (And you don't get a warning + confirmation-request for jumping outside the current function). (并且你没有收到警告+确认请求跳过当前功能)。

Then you can stepi from there. 然后你可以从那里stepi $pc is a generic gdb name for whatever the register is really called in the target architecture. $pc是一个通用的gdb名称,用于在目标体系结构中实际调用的寄存器。 eg RIP in x86-64. 例如,x86-64中的RIP。 (See also the bottom of the tag wiki for asm debugging tips for gdb.) (有关gdb的asm调试技巧,另请参阅标记wiki的底部。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM