graphviz绘制nginx函数调用图

以下是c的版本
c++代码去 [url]http://www.cnblogs.com/lanxuezaipiao/p/3450201.html[/url]
codeviz似乎只能支持gcc4.6,好久没更新了,
看这个
[url]https://github.com/Cheukyin/CodeSnippet/tree/master/python/SRCGraphviz/[/url]


目标建立 nginx的运行流程
参考
[url]https://www.ibm.com/developerworks/cn/linux/l-graphvis/[/url]
参考《深入剖析nginx》
javascript生成绘制.dot
参考
[url]http://stackoverflow.com/questions/6344318/pure-javascript-graphviz-equivalent/14866384[/url]
参考
[url]http://graphviz.org/content/cluster[/url]
my_debug.h

#ifndef MY_DEBUG_LENKY_H
#define MY_DEBUG_LENKY_H
#include <stdio.h>
void enable_my_debug( void ) __attribute__((no_instrument_function));
void disable_my_debug( void ) __attribute__((no_instrument_function));
int get_my_debug_flag( void ) __attribute__((no_instrument_function));
void set_my_debug_flag( int ) __attribute__((no_instrument_function));
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));

#ifndef MY_DEBUG_MAIN
extern FILE *my_debug_fd;
#else
FILE *my_debug_fd;
#endif
#endif

my_debug.c

#include <stdio.h>
#include <stdlib.h>

/* Function prototypes with attributes */
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));


static FILE *fp;


void main_constructor( void )
{
fp = fopen( "/usr/local/nginx_sendfile/sbin/trace.txt", "w" );
if (fp == NULL) exit(-1);
}


void main_deconstructor( void )
{
fclose( fp );
}


void __cyg_profile_func_enter( void *this, void *callsite )
{
fprintf(fp, "E%p\n", (int *)this);
}


void __cyg_profile_func_exit( void *this, void *callsite )
{
fprintf(fp, "X%p\n", (int *)this);
}

把my_debug.c和my_debug.h放到nginx的src/core/目录下
./configure后修改ojbs/Makefile文件

CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g3 -finstrument-functions
...
18 CORE_DEPS = src/core/nginx.h \
19 src/core/my_debug.h \
.....
84 HTTP_DEPS = src/http/ngx_http.h \
85 src/core/my_debug.h \
....

105 objs/nginx: objs/src/core/nginx.o \
106 objs/src/core/my_debug.o \
......
216 $(LINK) -o objs/nginx \
217 objs/src/core/nginx.o \
218 objs/src/core/my_debug.o \
......
329 modules:

331 objs/src/core/my_debug.o: $(CORE_DEPS) src/core/my_debug.c
332 $(CC) -c $(CFLAGS) $(CORE_INCS) \
333 -o objs/src/core/my_debug.o \
334 src/core/my_debug.c


make&&make install后
启动nginx,生成
/usr/local/nginx/sbin/trace.txt
文件类似
[code="java"]
# head trace.txt
E0x403f88
E0x41f5ac
X0x41f5ac
E0x403f88
X0x403f88
E0x410425
E0x40ff83
E0x40fa71
X0x40fa71
E0x40ad4b
[/code]
可以addr2line 40ad4b -e nginx -f
查看地址对应的函数名
使用
[url]https://www.ibm.com/developerworks/cn/linux/l-graphvis/[/url]
中的pvtrace
修改代码
symbols.h 中的

13 #define MAX_FUNCTIONS 20000
14 #define MAX_FUNCTION_NAME 5000

否函数太多会报错
stack.c里面也有个改成


#define MAX_ELEMENTS 500

pvtrace nginx
会得到
graph.dot
dot -Tpng graph.dot -o graph.png
如果.dot文件有??则是地址没识别出来,
就一两个,删除即可
也可以生成jpg,
这个.dot也可以用

生成svg的图
根据dot的格式生成svg图的js为


<html>
<head>
<meta charset="utf-8">
<title>Viz.js</title>
</head>
<body>
<script type="text/vnd.graphviz" id="cluster">
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
subgraph cluster_1 {
node [style=filled];
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}
</script>
<script src="viz.js"></script>
<script>
function inspect(s) {
return "<pre>" + s.replace(/</g, "<").replace(/>/g, ">").replace(/\"/g, """) + "</pre>"
}
function src(id) {
return document.getElementById(id).innerHTML;
}
function example(id, format, engine) {
var result;
try {
result = Viz(src(id), format, engine);
if (format === "svg")
return result;
else
return inspect(result);
} catch(e) {
return inspect(e.toString());
}
}
document.body.innerHTML += "<h1>Cluster (svg output)</h1>";
document.body.innerHTML += example("cluster", "svg");
</script>
</body>
</html>

结果如图
[img]http://dl2.iteye.com/upload/attachment/0096/1157/c3f4f19b-af01-35e3-afa6-9b140828484d.jpg[/img]
2017.8.15 nginx-1.13.4
[img]http://dl2.iteye.com/upload/attachment/0126/5439/c2d9193a-a686-3afc-bb9a-5c50e5be0ac8.png[/img]

附件中
graph.dot.jpg 下载后改成graph.dot用文本打开可以看到dot文件内容

nginx.conf前面要加上
master_process off;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值