之前一直好奇爲何 Clang Static Analyzer (CSA) 中 dump 函式都是以 JSON 的形式輸出的,今天纔發現原來是與檢視 ExplodedGraph 相關。
通過 dump.ViewExplodedGraph
這個 checker 可以將當前被分析程式碼的 ExplodedGraph 以 dot 檔案的形式報存下來。但其中的每一個 ExplodedNode 都依然是 JSON 格式的字串。如果需要清晰展現其中的內容,則需要 exploded-graph-rewrite
工具來對這份 dot 檔案進行處理。
該工具位於 LLVM 項目下的 ./clang/utils/analyzer/exploded-graph-rewriter.py
位置。使用該工具可以將剛剛生成的 ExplodedGraph 的 dot 檔案轉換爲對應的 SVG 檔案(其中使用了 GraphViz 負責格式轉換),並同時對每一個 ExplodedNode 中的 JSON 字串進行解析並生成對應的表格化展示,以方便查看。
處理前的 ExplodedNode(JSON 格式):
{ "state_id": 135, "program_points": [ { "kind": "Statement", "stmt_kind": "DeclRefExpr", "stmt_id": 627, "pointer": "0x5556f11554b8", "pretty": "x", "location": { "line": 3, "column": 20, "file": "temp.cpp" }, "stmt_point_kind": "PostLValue", "tag": null, "node_id": 8, "is_sink": 0, "has_report": 0 }, { "kind": "Statement", "stmt_kind": "DeclRefExpr", "stmt_id": 627, "pointer": "0x5556f11554b8", "pretty": "x", "location": { "line": 3, "column": 20, "file": "temp.cpp" }, "stmt_point_kind": "PostStmt", "tag": null, "node_id": 9, "is_sink": 0, "has_report": 0 } ], "program_state": { "store": { "pointer": "0x5556f1178008", "items": [ { "cluster": "x", "pointer": "0x5556f1177f70", "items": [ { "kind": "Direct", "offset": 0, "value": "0 S32b" } ]} ]}, "environment": { "pointer": "0x5556f11776d0", "items": [ { "lctx_id": 1, "location_context": "#0 Call", "calling": "f", "location": null, "items": [ { "stmt_id": 627, "pretty": "x", "value": "&x" } ]} ]}, "constraints": null, "equivalence_classes": null, "disequality_info": null, "dynamic_types": null, "dynamic_casts": null, "constructing_objects": null, "checker_messages": null } }
處理後的同一個 ExplodedNode: