跟踪源行级别的程序/功能执行

时间:2016-09-20 19:27:02

标签: debugging gdb tracing

有没有办法根据执行的源代码行记录特定函数(或整个程序)的执行情况?

Consdier我在gdb设置了一个断点来运行foo,然后重复调用step,它会告诉我这样的事情:

(gdb) break foo
Thread 1 "main" hit Breakpoint 1, foo () at foo.cpp:10
(gdb) step
foo () at foo.cpp:12
(gdb) step
foo () at foo.cpp:13
(gdb) step
foo () at foo.cpp:12
(gdb) step
foo () at foo.cpp:14

然后我重复一遍,直到foo的输出不再bt为止。这给了我执行的痕迹(foo.cpp:10-> 12-> 13-> 12-> 14),这对比较长控制流特别有用。

有没有办法用gdb执行此操作,还是有其他工具可以执行此操作?我只对确定性痕迹感兴趣,而不是采样。理想情况下,也可以对stepi(在指令级别)/ next执行此操作(无需输入子例程)。

1 个答案:

答案 0 :(得分:1)

基于this similar question,我能够为我的目的整理一个快速python脚本。幸运的是,需要更少的bug工作区:

import sys
import gdb
import os
import re

def in_frames(needle):
    """ Check if the passed frame is still on the current stack """
    hay = gdb.newest_frame()
    while hay:
        if hay == needle:
            return True
        hay = hay.older()
    return False

# Use this to reduce any kind of unwanted noise
def filter_step(output):
    output = re.sub(r'^.*No such file or directory\.\n', r'', output, flags=re.M)
    output = re.sub(r'^\d+\s+in\s+.*\n', r'', output, flags=re.M)
    return output

def step_trace(filename=None, step="step"):
    counter = 0
    if filename:
        output = ""
    frame = gdb.newest_frame()
    print("Stepping until end of {} @ {}:{}".format(frame.name(), frame.function().symtab, frame.function().line))
    while in_frames(frame):
        counter += 1
        if filename:
            output += filter_step(gdb.execute(step, to_string=True))
        else:
            gdb.execute(step)

    if filename:
        with open(filename, "w") as file:
            file.write(output)
    print("Done stepping through {} lines.".format(counter))

将跟踪输出到文件

(gdb) source step_trace.py
(gdb) python step_trace("filename.log")

或直接

(gdb) source step_trace.py
(gdb) python step_trace()
相关问题