GDB是否有一个"步骤到下一个呼叫"指令?

时间:2016-01-05 21:27:22

标签: gdb

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

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

这可能吗?

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

1 个答案:

答案 0 :(得分: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()
    
  • 要在调用后停止,您需要计算当前的堆栈深度,然后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() 
    

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

有相关文件: