原理
修改gcc的编译选项,使其在编译的过程中生成中间文件,类型为 .expand
用Egypt处理.expand文件使其生成.dot 文件
用graphviz处理.dot 文件,生成callgrapph
安装egypt
点击egypt1.10(www.gson.org/egypt/download/egypt-1.10.tar.gz),下载egypt1.10
tar zxvf egypt-1.10.tar.gz
cd egypt-1.10
perl Makefile.PL
make
sudo make install
修改编译选项
在官方文档(www.gson.org/egypt/egypt.html)中,用以下命令编译命令可以生成.expand 文件
make CFLAGS=-fdump-rtl-expand
在Linux kernel中要通过修改Makefile来达到修改编译选项的目的,修改如下:
第一种修改方式为:
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-Werror-implicit-function-declaration \
-Wno-format-security \
-std=gnu89 \
-fdump-rtl-expand //添加这一行,注意上一行要有\
第二种修改方式为:
KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
KBUILD_CFLAGS += $(call cc-option,-fdump-rtl-expand,) //添加这一行
KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
任何一种都可以,修改完之后执行以下命令可以得到.expand 文件,android内核也可以这样修改Makefile,但是得和android源码一起编译
make -j16
为了方便起见,在Makefile中添加make clean 选项,可以在执行make clean时删除生成的.expand 文件
clean: $(clean-dirs)
$(call cmd,rmdirs)
$(call cmd,rmfiles)
@find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '*.ko.*' \
-o -name '*.expand' \ //添加这一行
-o -name '*.dwo' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.symtypes' -o -name 'modules.order' \
-o -name modules.builtin -o -name '.tmp_*.o.*' \
-o -name '*.gcno' \) -type f -print | xargs rm -f
生成callgraph
执行以下命令可以生成init 中main 的callgraph
egypt /linux-4.10.9/init/main.c.213r.expand | dot -Grankdir=LR -Tsvg -o callgraph.svg
-Grankdir=LR //使callgraph从左往右生长
-Tsvg //生成.svg的矢量图,也可以用-Tpng
如果要生成多个.expand 文件(a.expand,b.expand)的call graph
egypt a.expand b.expand | dot -Grankdir=LR -Tsvg -o callgraph.svg
也可以使用通配符 * 来生成某一个文件下的.expand的总的callgraph
egypt /linux-4.10.9/init/*.expand | dot -Grankdir=LR -Tsvg -o callgraph.svg
不支持上传.svg的图片,就截个图好了,这样子