Chinaunix首页 | 论坛 | 博客
  • 博客访问: 170537
  • 博文数量: 33
  • 博客积分: 2143
  • 博客等级: 大尉
  • 技术积分: 807
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 10:24
个人简介

Show me the money

文章分类

全部博文(33)

文章存档

2015年(1)

2013年(1)

2011年(12)

2010年(14)

2009年(2)

2008年(2)

2005年(1)

我的朋友

分类:

2010-02-09 15:39:43

1. 原理

参见  http://www.ibm.com/developerworks/cn/linux/l-graphvis/#download

2. 改进

在实际应用中,打印信息中可能还包含有很多其它的调试诊断信息;考虑到shell强大的文本处理能力,故用shell script重新实现。

基本处理流程为:

1.       log文件中提取calltrace信息

2.       分析函数调用关系,生成模板文件

3.       通过模板文件生成调用关系图

## http://www.ibm.com/developerworks/cn/linux/l-graphvis

 

#=========================================================================

#

# Copyright (C) 2010 P.R.C

#

# This program is free software; you can redistribute it and/or modify

# it under the terms of the GNU General Public License version 2 as

# published by the Free Software Foundation.

#

# This script is used to create a call-trace graph from log messages.

#

# Changelog:

#

#  2010/2/9:  P.R.C

#               - The first available version

#

#=========================================================================

 

set -e

set -o pipefail

 

export LANG=en_US

 

if [ -z "$2" ]; then

    cat >&2 <

Usage:

    $(basename $0 .sh) EXEFILE JPGFILE

EOF

    exit 1

fi

 

exe_file=$1

jpg_file=$2

 

TF_OPT=~opts.txt

TF_NAME=~name.txt

TF_N_DOT=~n.dot

LF_TRACE=trace.txt

 

opts=$(gawk '!($2 in a){print $2;a[$2]=1;}' $LF_TRACE)

 

echo "$opts" > $TF_OPT

addr2line -e $exe_file -s -f $opts > $TF_NAME

 

gawk -- '

BEGIN {

    STDERR = "/dev/stderr"

    TAB = "  "

    FONTS = "[fontname=\"Arial Bold\" fontsize=\"9\"]"

    nr_funcs = 0

}

FILENAME==ARGV[1]{

    addr[FNR] = tolower($1)

}

FILENAME==ARGV[2]{

    if( FNR % 2 != 0 ) {

        fnr = (1 + FNR) / 2;

        addr_map[addr[fnr]] = $1

    }

}

FILENAME==ARGV[3]{

    if(FNR == 1)

        delete addr;

    if($1 == "E") {

        fa = tolower($2)

        prev_func = cur_func;

        cur_func = addr_map[fa];

        stack[++stkptr] = cur_func;

        if(prev_func != "") {

            y = prev_func " -> " cur_func

            if( !(y in links) ) {

                order[++nr_funcs] = y

                links[y] = 1

            }

            calls[prev_func] += 1

            calls[cur_func]  += 0

        }

    } else if($1 == "X") {

        if( stkptr == 0 ) {

            printf("symbol stack overflow!") >STDERR;

            exit_status = 1;

            exit exit_status

        }

        cur_func = stack[--stkptr]

    }

}

END {

    if(exit_status == 0) {

        delete links

        print "digraph G {"

        for(i=1; i<=nr_funcs; i++)

            printf(TAB "%s\n", order[i]);

        for(i in calls) {

            if( calls[i] > 0 )

                printf(TAB "%s [shape=rectangle] " FONTS "\n", i);

            else

                printf(TAB "%s [shape=ellipse] "  FONTS "\n", i);

        }

        print "}\n"

    }

}' $TF_OPT $TF_NAME $LF_TRACE > $TF_N_DOT

 

dot -Tjpg $TF_N_DOT -o $jpg_file

rm -f $TF_OPT $TF_NAME $TF_N_DOT

 

3. 验证环境

GNU bash, version 3.00.16(14)-release (i686-pc-cygwin)

gcc version 3.3.1 (cygming special)

GNU addr2line 2.15.90 20040312

GNU Awk 3.1.5

graphviz-2.26.3

结束语

使用开源软 件和少量的中间代码,只需要花很少的时间就可以开发出非常有用的项目。通过使用对应用程序进行分析的几个 GNU 编译器扩展,可以使用 Addr2line 工具进行地址转换,并对 Graphviz 应用程序进行图形可视化,然后您就可以得到一个程序,该程序可以对应用程序进行分析,并展示一个说明调用链的定向图。通过图形来查看一个应用程序的调用链 对于理解应用程序的内部行为来说非常重要。在正确了解调用链及其各自的频率之后,这些知识可能对调试和优化应用程序非常有用。

 

文件: pvtrace.rar
大小: 201KB
下载: 下载

 

 5效果图

阅读(1323) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~