GDB是否具有“下一步呼叫”功能?指令? [英] Does GDB have a "step-to-next-call" instruction?

查看:211
本文介绍了GDB是否具有“下一步呼叫”功能?指令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



是可能的吗?



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

解决方案

简单回答:不, -nxt-call 不是GDB命令的一部分。



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



我不确定要在调用之前还是之后停止指令执行。




  • 要在之前停止,您需要 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()

    而真:
    current_pc = addr2num(gdb.selected_frame()。read_register(pc))
    disa = arch.disassemble(current_pc)[0]
    if disa [asm]中的call:#或startswith?
    break

    SILENT = True
    gdb.execute(stepi,to_string = SILENT)

    print(step-before-next-call )
    print({}:{}。格式(hex(int(disa [addr])),disa [asm]))

    def addr2num(addr):
    try:
    return int(addr)#Python 3
    除外:
    return long(addr)#Python 2

    StepBeforeNextCall()


  • 要在之后停止调用,计算当前的堆栈深度,然后 step ,直到它更深:

      import gdb 
    $ b $ def callstack_depth():
    depth = 1
    frame = gdb.newest_frame()
    while frame is not None:
    frame = frame.older()
    depth + = 1
    返回深度

    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()

    #再深一步
    current_depth == start_depth:
    SILENT = True
    gdb.execute(step,to_string = SILENT)
    current_depth = callstack_depth()

    #显示有关新框架的信息
    gdb.execute(frame 0)

    StepToNextCall()


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



相关文件存在:


WinDBG and the related windows kernel debuggers support a "pc" command which runs the target until reaching the next call statement (in assembly). In other words, it breaks just prior to creating a new stack frame, sort of the opposite of "finish". "Start" in GDB runs until main starts, but in essence I want 'start' but with a wildcard of "any next frame".

I'm trying to locate a similar functionality in GDB, but have not found it.

is this possible?

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

解决方案

Simple answer: no, step-to-next-call is not part of GDB commands.

GDB/Python-aware answer: no, it's not part of GDB commands, but it's easy to implement!

I'm not sure to understand if you want to stop before or after the call instruction execution.

  • To stop before, you need to stepi/nexti (next assembly instruction) until you see call in the current instruction:

    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()
    

  • To stop after the call, you compute the current stack depth, then step until it's deeper:

    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() 
    

just put that in a file, source it with GDB (or in your .gdbinit) and that will provide you the new commands step-before-next-call and step-to-next-call.

Relevant documentation is there:

这篇关于GDB是否具有“下一步呼叫”功能?指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆