gcc自动画流程图

1907阅读 0评论2009-07-30 linuxmemo
分类:C/C++

本程序來源於 http://www.ibm.com/developerworks/cn/linux/l-graphvis/
我主要是对程序进行了改进。画出的图信息更丰富。
注意!
0.阅读本文前先阅读http://www.ibm.com/developerworks/cn/linux/l-graphvis/
1.static函数不能画,解决方法:make的时候将static定义成空 static=
2.addr2line要和gcc配套,gcc是mips的,addr2line也得是mips的。
3.編譯生成的image被strip程序去掉了符號表,則必須修改makefile,將strip的處理去掉。
4.编译可執行程序時,加选项: -g -finstrument-functions

以下是代码:
=============================instrument.c============================
#include
#include
void main_constructor( void ) __attribute__ ((no_instrument_function, constructor));
void main_destructor( void ) __attribute__ ((no_instrument_function, destructor));
void __cyg_profile_func_enter( void *, void * ) __attribute__ ((no_instrument_function));
void __cyg_profile_func_exit( void *, void * ) __attribute__ ((no_instrument_function));
#undef static
static FILE *fp;
void main_constructor( void )
{
  fp = fopen( "/var/run/trace.txt", "w" );
  if (fp == NULL) exit(-1);
}
void main_deconstructor( void )
{
  if (fp)
    fclose( fp );
}
void __cyg_profile_func_enter( void *this, void *callsite )
{
  if (fp)
    fprintf(fp, "%p:%p\n", (int *)callsite,(int *)this);
}
void __cyg_profile_func_exit( void *this, void *callsite )
{
        ;
}
============pvtrace python脚本,windows用户需要安装python================
#!/usr/bin/python
import os, sys
addrlist = {}
addr_first = {}
addr_last = {}
namelist = {}
first_stamp = {}
last_stamp = {}
time = 0
def addr2line(addr):
    cmd = "addr2line -e " + sys.argv[1] + " -fs " + addr;
    p = os.popen(cmd);
    name = p.readline();
    return name.strip();

def record(line):
    global time
    line = line.strip();
    ca=tuple(line.split(":"));
    addrlist[ca] = addrlist.get(ca,0)+1;
    time = time + 1;
    if 0 == addr_first.get(ca,0):
        addr_first[ca] = time;
    addr_last[ca] = time;

def translate():
    for (x,y) in addrlist:
        ca = (addr2line(x),addr2line(y));
        namelist[ca] = namelist.get(ca,0) + addrlist[(x,y)]
        if 0 == first_stamp.get(ca,0):
            first_stamp[ca] = addr_first[(x,y)];
        last_stamp[ca] = addr_last[(x,y)]

def output():
    first_sorted = first_stamp.values();
    first_sorted.sort();
    last_sorted = last_stamp.values();
    last_sorted.sort(reverse=True);
    for ((x,y),z) in namelist.iteritems():
        print x,"->",y,"[label=\"",1+first_sorted.index(first_stamp[(x,y)]),"|",z,"|", -1-last_sorted.index(last_stamp[(x,y)]),"\"]"

if len(sys.argv) !=3:
    print """Usage: pvtrace """
    exit(-1)
for line in file(sys.argv[2]):
    record(line);
translate();
print "digraph g{"
print "rankdir=LR"
output();
print "}"
===============================================================================
然后用dot命令画图。
上一篇:杂项
下一篇:博客已升级,请注意变更地址