go-callvis 源碼分析
go-callvis 是一個可視化調用調用鏈路圖的靜態(tài)源碼分析工具
https://github.com/ofabry/go-callvis它的實現非常簡潔
examples handler.go output.goMakefile analysis.go go.mod images version.goREADME.md dot.go go.sum main.go
首先看下main.go文件
首先解析了一系列參數然后調用
Analysis = new(analysis)if err := Analysis.DoAnalysis("", tests, args); err != nil {log.Fatal(err)}
最后起了一個http服務,可以支持在線可視化
type analysis struct {opts *renderOptsprog *ssa.Programpkgs []*ssa.Packagemains []*ssa.Packageresult *pointer.Result}
定義在analysis.go文件里,重點是通過下面這個函數進行代碼分析的
func (a *analysis) DoAnalysis(dir string,tests bool,args []string,) error
調用
"golang.org/x/tools/go/packages"里面的
initial, err := packages.Load(cfg, args...)加載包里面所有的文件,然后調用
"golang.org/x/tools/go/ssa/ssautil"里面的
prog, pkgs := ssautil.AllPackages(initial, 0)prog.Build()
對源碼進行ssa轉化
然后找到入口的main函數
mains, err := mainPackages(pkgs)就是判斷包名和函數名
p.Pkg.Name() == "main" && p.Func("main")然后用
"golang.org/x/tools/go/pointer"的指針分析,進行依賴分析
result, err := pointer.Analyze(config)至此,完成了源碼的依賴分析,然后應用dot語言,轉化成圖像。
func outputDot(fname string, outputFormat string) {// get cmdline default for analysisAnalysis.OptsSetup()if e := Analysis.ProcessListArgs(); e != nil {log.Fatalf("%v\n", e)}output, err := Analysis.Render()
SSA在Go1.7中被引入,這個特性對編譯器的性能有很大的提高,但是也導致編譯過程有些減速。下面來結合網上的資糧和書籍,簡單說明一下SSA以及SSA的應用。
SSA 代表 static single-assignment,是一種IR(中間表示代碼),要保證每個變量只被賦值一次。這個能幫助簡化編譯器的優(yōu)化算法。
y := 1
y := 2
x := y
比如上面這段代碼,y = 1其實是不可用的,這個要通過定義的可達分析來確定y是要用1還是2,而SSA有一個標識符可以稱之為版本或者“代“。
y1 := 1
y2 := 2
x1 := y2
這樣就沒有任何間接值了。用SSA表示的好處是對于同一個變量的無關使用表示成不同“代”,可以方便很多編譯器的優(yōu)化算法的實現。
指向分析是一種用于分析指針和內存引用所指向的變量或內存地址的靜態(tài)代碼分析技術。指向分析技術是很多更為復雜的代碼分析技術的基礎,例如編譯優(yōu)化,代碼缺陷檢測以及指針修改影響分析。
指向分析,是指通過對源程序的分析近似地求出源程序中指針表達式所指向的目標。
推薦閱讀
評論
圖片
表情
