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()
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-call和step-to-next-call.
有相关文件: