GDB是否有"逐步调用"指令?

Bra*_*rad 2 gdb

WinDBG和相关的Windows内核调试器支持"pc"命令,该命令运行目标直到到达下一个调用语句(在汇编中).换句话说,它在创建新的堆栈帧之前就中断了,与"完成"相反.GDB中的"开始"运行直到主要开始,但实质上我想要"开始",但带有"任何下一帧"的通配符.

我试图在GDB中找到类似的功能,但还没有找到它.

这可能吗?

示例WinDBG doc:http://windbg.info/doc/1-common-cmds.html#4_expr_and_cmds

Kev*_*vin 6

简单回答:不,step-to-next-call不是GDB命令的一部分.

GDB/Python感知答案:不,它不是GDB命令的一部分,但它很容易实现!

我不确定你是否想在call指令执行之前或之后停止.

  • 在之前停止,您需要stepi/nexti(下一个汇编指令)直到您call在当前指令中看到:

    import gdb
    
    class StepBeforeNextCall (gdb.Command):
        def __init__ (self):
            super (StepBeforeNextCall, self).__init__ ("step-before-next-call",
                                                       gdb.COMMAND_OBSCURE)
    
        def invoke (self, arg, from_tty):
            arch = gdb.selected_frame().architecture()
    
            while True:
                current_pc = addr2num(gdb.selected_frame().read_register("pc"))
                disa = arch.disassemble(current_pc)[0]
                if "call" in disa["asm"]: # or startswith ?
                    break
    
                SILENT=True
                gdb.execute("stepi", to_string=SILENT)
    
            print("step-before-next-call: next instruction is a call.")
            print("{}: {}".format(hex(int(disa["addr"])), disa["asm"]))
    
    def addr2num(addr):
        try:
            return int(addr)  # Python 3
        except:
            return long(addr) # Python 2
    
    StepBeforeNextCall()
    
    Run Code Online (Sandbox Code Playgroud)
  • 通话结束后停止,您需要计算当前的堆栈深度,然后step直到它更深:

    import gdb
    
    def callstack_depth():
        depth = 1
        frame = gdb.newest_frame()
        while frame is not None:
            frame = frame.older()
            depth += 1
        return depth
    
    class StepToNextCall (gdb.Command):
        def __init__ (self):
            super (StepToNextCall, self).__init__ ("step-to-next-call", 
                                                   gdb.COMMAND_OBSCURE)
    
        def invoke (self, arg, from_tty):
            start_depth = current_depth =callstack_depth()
    
            # step until we're one step deeper
            while current_depth == start_depth:
                SILENT=True
                gdb.execute("step", to_string=SILENT)
                current_depth = callstack_depth()
    
            # display information about the new frame
            gdb.execute("frame 0")
    
    StepToNextCall() 
    
    Run Code Online (Sandbox Code Playgroud)

只需将它放在一个文件中,source它与GDB(或在你的.gdbinit)中,它将为您提供新的命令step-before-next-callstep-to-next-call.

有相关文件: