2016年2月2日 星期二

大型專案的原始碼分析--兼論 preprocessor

在分析原始碼的時候,遇到巨集定義總是令人又愛又恨;愛的是它在寫得好的時候(或讀的人狀況好的時候XD)是可以增進理解;恨是是當它寫得不好,或已經看得很累的時候,這時經常理解不能(冏rz)...

可TMD那精美的死線還是擺在那裏啊,怎辦呢?只好直面 preprocessor  了!

(先導知識: GNU: The C Preprocessor 導讀 )

方法一:改寫 Makefile 以展開所有巨集,順便得到 #include 路徑


例如,原來 Makefile 當中有以下指令:
.c.o:
@$(MKDEPDIR)
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $(PROFILING_CFLAGS) $<


將上述指令改寫
.c.o:
@$(MKDEPDIR)
$(CC) -E $(CPPFLAGS) $(ALL_CFLAGS) $(PROFILING_CFLAGS) -o $@ $<

然後在 terminal 中,執行以下指令
rm *.o
make
rename -v s/\.o/\.i/ *.o

如此可得到副檔名為 *.i 的展開的原始碼,所有的 #include 還有巨集定義等等都被展開了。還有一些 gcc 的參數可以讓輸出比較好看,例如 -CC 可以保留註解等,就按各人需要調整囉~~

(正統的做法參見 http://www.gnu.org/software/cflow/manual/html_node/Makefiles.html#Makefiles)
(前提是你要很熟 Makefile 的語法)

為何需要這個呢?因為目前基於 tags 的原始碼分析程式,無論是 ctags, cscope, gnu cflow ,遇到 INLINE 的函數都失效,只好暫時先這樣處理…但很奇妙的 gnu global / gtags 可以正確處理 ,之後肯定要專文介紹一下

方法二:利用之前執行 make 觀察 stdout 得到的 -I 參數,以 --cpp -I 參數執行 gnu cflow


根據先前執行 make 的螢幕輸出,得到 -I 參數,以 emacs 24.5 的原始碼為例:

cflow --cpp -b --emacs -T \
 -I. -I../lib -I./../lib -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12   -I/usr/include/freetype2       -I/usr/include/libxml2   -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include   -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include   -I/usr/include/freetype2   -I/usr/include/freetype2 -I/usr/include/p11-kit-1 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include \
 vm-limit.c dispnew.c frame.c scroll.c xdisp.c menu.c xmenu.c window.c charset.c coding.c category.c ccl.c character.c chartab.c bidi.c cm.c term.c terminal.c xfaces.c xterm.c xfns.c xselect.c xrdb.c xsmfns.c xsettings.c gtkutil.c emacsgtkfixed.c dbusbind.c emacs.c keyboard.c macros.c keymap.c sysdep.c buffer.c filelock.c insdel.c marker.c minibuf.c fileio.c dired.c cmds.c casetab.c casefiddle.c indent.c search.c regex.c undo.c alloc.c data.c doc.c editfns.c callint.c eval.c floatfns.c fns.c font.c print.c lread.c syntax.c unexelf.c bytecode.c process.c gnutls.c callproc.c region-cache.c sound.c atimer.c doprnt.c intervals.c textprop.c composite.c xml.c gfilenotify.c profiler.c decompress.c xfont.c ftfont.c xftfont.c ftxfont.c fontset.c fringe.c image.c xgselect.c terminfo.c lastfile.c \
 -o emacs.b.cflow

沒有留言:

張貼留言