【发布时间】:2018-09-27 08:26:52
【问题描述】:
我正在尝试查看 gcc 是否可以提供更多信息,我可以使用这些信息从 C 源代码创建控制流图,然后使用它来检查 Gcov .gcov 输出中执行的测试用例所采用的路径.到目前为止,我最好的候选人是使用-fdump-tree-cfg 和lineno 选项(-fdump-tree-cfg-lineno),但结果文件对我来说仍然是有限的,因为每个函数的节点信息都是分开的。像这样的:
;; Function main (main, funcdef_no=13, decl_uid=3054, cgraph_uid=13, symbol_order=13)
Removing basic block 7
Merging blocks 5 and 6
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2 3 4 5 6
;; 2 succs { 3 4 }
;; 3 succs { 5 }
;; 4 succs { 5 }
;; 5 succs { 6 }
;; 6 succs { 1 }
main ()
{
int number;
int D.3066;
<bb 2> [0.00%]:
[evenodd.c:7:5] printf ([evenodd.c:7:12] "\nEnter a number: ");
[evenodd.c:8:5] scanf ([evenodd.c:8:11] "%d", [evenodd.c:8:5] &number);
[evenodd.c:10:2] number.0_1 = number;
[evenodd.c:10:2] checkNegative (number.0_1);
[evenodd.c:12:17] number.1_2 = number;
[evenodd.c:12:17] number.2_3 = (unsigned int) number.1_2;
[evenodd.c:12:17] _4 = number.2_3 & 1;
[evenodd.c:12:7] if (_4 == 0)
goto <bb 3>; [0.00%]
else
goto <bb 4>; [0.00%]
<bb 3> [0.00%]:
[evenodd.c:13:9] number.3_5 = number;
[evenodd.c:13:9] printf ([evenodd.c:13:16] "%d is Even\n", number.3_5);
[0:0] goto <bb 5>; [0.00%]
<bb 4> [0.00%]:
[evenodd.c:15:9] number.4_6 = number;
[evenodd.c:15:9] printf ([evenodd.c:15:16] "%d is Odd\n", number.4_6);
<bb 5> [0.00%]:
[evenodd.c:18:9] D.3066 = 0;
number = {CLOBBER};
<L4> [0.00%]:
return D.3066;
}
;; Function checkNegative (checkNegative, funcdef_no=14, decl_uid=3057, cgraph_uid=14, symbol_order=14)
;; 1 loops found
;;
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2 3 4 5
;; 2 succs { 3 4 }
;; 3 succs { 5 }
;; 4 succs { 5 }
;; 5 succs { 1 }
checkNegative (int number)
{
<bb 2> [0.00%]:
[evenodd.c:23:4] if (number < 0)
goto <bb 3>; [0.00%]
else
goto <bb 4>; [0.00%]
<bb 3> [0.00%]:
[evenodd.c:24:9] printf ([evenodd.c:24:16] "%d is Negative\n", number);
[0:0] goto <bb 5>; [0.00%]
<bb 4> [0.00%]:
[evenodd.c:26:9] printf ([evenodd.c:26:16] "%d is Positive\n", number);
<bb 5> [0.00%]:
[evenodd.c:28:1] return;
}
这意味着我的解析器需要识别 main 函数中的每个函数调用,然后合并它们的节点信息,这对我来说是一项非常艰巨的任务。
所以我从this documentation 遇到了-fdump-tree 的-graph 选项,但我不知道如何使用它。正如文档描述的那样:
‘graph’
For each of the other indicated dump files (-fdump-rtl-pass),
dump a representation of the control flow graph suitable for
viewing with GraphViz to file.passid.pass.dot. Each function in
the file is pretty-printed as a subgraph, so that GraphViz can
render them all in a single plot.
This option currently only works for RTL dumps, and the RTL
is always dumped in slim form.
我不知道 GraphViz 是如何工作的,但由于它能够将所有函数的子图呈现为单个图(我假设这意味着所有子图都与主图合并为单个图),这意味着提供的信息by -graph 更完整,更容易创建控制流图。
由于我无法理解它的含义,我尝试按原样使用该选项 (-fdump-tree-cfg-lineno-graph),但结果仍然与 -fdump-tree-cfg-lineno 的结果相同。
如何使用它?
【问题讨论】:
-
我认为您使用它正确,您没有看到
.dot-file 正在创建吗?适用于 GCC 5.5.0。 -
@xaizek 显然它没有出现在我正在使用的机器上。
.dot文件是在我自己的笔记本电脑上创建的。两者都有 GCC 7.2.0(MinGW-W64 项目)。 -
@xaizek 是的,它确实有效。我在另一台计算机上尝试过并创建了
.dot文件。错在我这边。
标签: c testing gcc control-flow-graph