2016-09-20 38 views
1

有一种方法,以记录特定功能的在执行行源代码方面的执行(或整个程序)?跟踪上的源极线电平的程序/功能执行

Consdier我gdb设置断点的功能foo,然后repetedly打电话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(不需要输入子程序)完成。

+0

看起来调试剥离代码或者不提供源码。并且该代码是C++,而不是C. – Olaf

+0

实际上,对于此特定问题,源代码不可用,但未剥离。当然源代码级别不适用于剥离的二进制文件。我坚信这个问题适用于C和C++,因此根据C标签wiki,对两者进行标记是合适的。唯一的区别是demangling。如果你删除了标签,请说明C的答案不适合C++。 – Zulan

+0

似乎有一个[类似的问题](http://stackoverflow.com/questions/6947389/how-to-print-every-executed-line-in-gdb-automatically-until-a-given-breakpoint-i ),不同之处在于最终条件。 – Zulan

回答

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