首页>Program>source

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

假设我有以下类似内容

int main()
{
  caller_f1() {  
   f1();  // breakpoint  
   f2() } // want to skip f2() and jump 
  caller_f2() { // jump to this this location ??       
   f1();  
   f2(); }  
}
最新回答
  • 2021-1-10
    1 #

    似乎有一个跳转命令,正是您要寻找的命令:

    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

  • 2021-1-10
    2 #

    要在 新地址,使用 jump (简写: j ):

    jump LINENUM
    jump *ADDRESS
    

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

    linenum可以是任何 linespec 表情,像 +1 下一行。

    有关方便的 skip的相关问题,请参见@gospes的答案 宏正是这样做的。


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

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

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

    gcc的手册建议使用 -Og 对于通常的编辑-编译-调试周期,但即使是最优化的水平也将破坏 jump 以及变量的异步修改.如果您不想在调试时执行此操作,那么这是一个不错的选择,尤其是对于 -O0 运行太慢,这是一个问题。


    To set program-counter / instruction-pointer to a new address without resuming ,您还可以使用以下方法:

    set $pc = 0x4005a5
    

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

    这等效于 tbreak + jump ,但是您不能使用行号,只能使用指令地址. (并且您不会收到警告+确认请求,请跳到当前功能之外。)

    然后您就可以 stepi 从那里. $pc 是通用gdb名称,用于在目标体系结构中实际调用的寄存器.例如 x86-64中的RIP. (有关gdb的asm调试技巧,另请参见x86标签wiki的底部。)

  • r:通过过滤隐藏对象来减少绘图的PDF文件大小
  • .net:我可以在项目/解决方案级别上设置Option Explicit和Option Strict吗?