WinDBG和相关的Windows内核调试器支持"pc"命令,该命令运行目标直到到达下一个调用语句(在汇编中).换句话说,它在创建新的堆栈帧之前就中断了,与"完成"相反.GDB中的"开始"运行直到主要开始,但实质上我想要"开始",但带有"任何下一帧"的通配符.
我试图在GDB中找到类似的功能,但还没有找到它.
这可能吗?
示例WinDBG doc:http://windbg.info/doc/1-common-cmds.html#4_expr_and_cmds
简单回答:不,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-call
和step-to-next-call
.
有相关文件:
Python API内容表
基本的Python
Python表示架构
从Python访问劣质堆栈帧.