Chinaunix首页 | 论坛 | 博客
  • 博客访问: 145478
  • 博文数量: 54
  • 博客积分: 2682
  • 博客等级: 少校
  • 技术积分: 580
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 20:56
文章分类
文章存档

2012年(2)

2011年(10)

2010年(28)

2009年(14)

我的朋友

分类: C/C++

2011-06-04 08:03:50

这几天弄出个nginx源码callgraph。结果在附件nginx.svg里,用firefox或chrome打开,然后按住ctrl键,向上猛滚鼠标轮子~

这个图(左边框框的函数调用右边框框的函数,图的整体顺序是左到右)带来的好处是:
1. 能迅速知道函数所处的“阶层”。知道阅读顺序。比如nginx的内存池代码在svg图的最右边,ngx_palloc等函数。表示这个模块是支撑模块,先读这个就利于理解高层的东西~
2. 若一个节点入度过高,表示这个函数需要重点优化和重点理解其接口。
3. 简化阅读量。这个图的生成过程是:修改Makefile,对CFLAGS加上-fdump-rtl-expand;make;egypt *.expand | dot --dot参数 -Tsvg > nginx.svg。所以根据生成过程就可以知道,没被编译的代码肯定不会进入这个callgraph,nginx中有些地方的源码为了迎合多个平台,有很多#if #elif,这样容易混淆视线。编译器参与这个过程有个好处,我注意到有几个函数明明被调用了,却没被放到图中,我猜测是编译器觉得这个函数太短小了,做了处理;还有节点名字一定是函数,源码有些地方会出现对函数的宏封装。比如#define ngx_log_err(level, log, args...) ngx_log_error_core ....那么宏ngx_log_error就不会出现在callgraph中,而只显示ngx_log_error_core被调用了。再一个例子是:ngx_os_specific_status也是如此,虽然是函数,但是里面除了调用宏没做任何别的事,所以被踢出了callgraph,也算是简化了阅读量。
4. 不需要对数据类型有充分理解便可开始阅读代码。nginx代码结构(struct)繁多,而且结构里面的成员极多,加上注释十分少,所以一开始就阅读结构除了知道成员是什么类型的语法信息外,得不到任何这个成员起什么作用的语义信息。举例来说,图中的ngx_reusable_connection函数,处于被调用的最底层,虽然使用了ngx_connection_s这个庞然大物,但是阅读的时候,我只需要关心reusable和queue便知道这个函数的目的是把c从一个队列中删除放到另外一个队列中。

BTW: 本人还远未触及核心代码,只是画了个图YY一下~
PLUS:若你和我一样使用vim+cscope看代码,那么在~/.vim/plugin/nginx.vim中加入如下这行会简化nginx类型定义的跳转~

nmap F :cs find g =substitute(expand(""),'_t$', '_s', "g")

按大写F就可以了

文件: nginx.zip
大小: 372KB
下载: 下载

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

chinaunix网友2011-06-28 21:38:21

您好,我现在在弄egypt,请问make以后生成的.expand文件在哪里,我找不到?