当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《GDB是否有"逐步调用"指令?》经验,为你挑选了1个好方法。

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

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

这可能吗?

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



1> Kevin..:

简单回答:不,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.

有相关文件:

Python API内容表

基本的Python

Python表示架构

从Python访问劣质堆栈帧.

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有