您可以将 –-union 和 codean 结合使用来处理多个动态报告。它可用来显示、保存测试套件中运行 discover 后生成的结果,以及显示相应的新问题或已修复的问题。以下示例显示了如何使用 discover 和 codean -–union。
这将清除 a.out.analyze/dynamic/ 下的所有现有动态报告。
缺省情况下,每次运行的结果都会保存在一个单独的文件中,latest 报告是最新结果的符号链接。例如,运行 a.out 5 次后,a.out.analyze/dynamic/ 目录如下所示:
$ ls -l a.out.analyze/dynamic/ total 11 lrwxrwxrwx 1 demoUser demo 18 May 1 15:14 latest -> ./latest.AAAvCaWri -rwxrwxrwx 1 demoUser demo 588 Apr 30 10:05 latest.AAACRaOId -rwxrwxrwx 1 demoUser demo 587 Apr 15 15:03 latest.AAAQcayId -rwxrwxrwx 1 demoUser demo 587 Apr 30 10:05 latest.AAAe5aWId -rwxrwxrwx 1 demoUser demo 587 Apr 15 15:03 latest.AAAlCaGId -rwxrwxrwx 1 demoUser demo 587 May 1 15:14 latest.AAAvCaWri
使用 discover 准备好报告后,可以使用 codean 处理 a.out.analyze/dynamic/ 下的所有动态报告。
显示单独的报告:
% codean --union -d a.out
codean 命令按字母顺序处理 a.out.analyze/dynamic 下的所有单独的动态报告。它只生成文本输出(即,不是组合的 Analytics 输出或 HTML 输出,与标准 codean 运行不同)。对于同一问题,不管呈现的是哪种报告,该问题的详细信息仅显示在第一个实例。对于该问题的其他表现形式,codean 仅显示有限的信息,如下所示:
LEAK 1: repeated, 1 blocks, 4 bytes ERROR 1: repeated 1 time
discover 信息仅在整个报告的结尾处显示一次,以汇总整个测试套件的问题计数。本示例的完整 codean 输出如下所示:
$ codean --union -d a.out
Displaying dynamic report of a.out.analyze/dynamic/latest.AAACRaOId:
ERROR 1 (UMR): accessing uninitialized data in "*i" at address 0x8090010 (4 bytes) on the heap at:
main() + 0xe1 <hello.c : 10>
5: {
6: int *i = malloc(sizeof(int));
8: int j = 0;
10:=> j = *i;
12: return 0;
_start() + 0x71
was allocated at (4 bytes):
main() + 0x5e <hello.c : 6>
2: #include <stdio.h>
4: int main()
5: {
6:=> int *i = malloc(sizeof(int));
8: int j = 0;
_start() + 0x71
Displaying dynamic report of a.out.analyze/dynamic/latest.AAAQcayId:
LEAK 1: 1 allocation with total size of 4 bytes
main() + 0x5e <hello.c : 6>
2: #include <stdio.h>
4: int main()
5: {
6:=> int *i = malloc(sizeof(int));
8: int j = 0;
_start() + 0x71
ERROR 1: repeated 1 time
Displaying dynamic report of a.out.analyze/dynamic/latest.AAAe5aWId:
LEAK 1: repeated, 1 blocks, 4 bytes
ERROR 1: repeated 1 time
Displaying dynamic report of a.out.analyze/dynamic/latest.AAAlCaGId:
LEAK 1: repeated, 1 blocks, 4 bytes
ERROR 1: repeated 1 time
Displaying dynamic report of a.out.analyze/dynamic/latest.AAAvCaWri:
LEAK 1: repeated, 1 blocks, 4 bytes
ERROR 1: repeated 1 time
DISCOVER SUMMARY for a.out: 1 non-leak issues, 1 leak issues
unique errors : 1 (5 total)
unique warnings : 0 (0 total)
unique leaks : 1 (4 blocks, 16 bytes)
unique possible leaks : 0 (0 blocks, 0 bytes)
请注意,对确定性泄露和可能性泄露的处理方式有所不同。对于标准 codean 运行,泄露是确定性泄露还是可能性泄露完全取决于 Analytics 报告中的置信度值。但是,对于“测试套件”codean 运行,如果泄露在任意动态报告中为确定性泄露,那么它在其余的报告中也将被标识为确定性泄露,无论这些报告中的置信度值为何。请参见以下“测试套件”codean 和标准 codean 报告中 LEAK 1 的显示方式:
$ codean --union -d a.out
Displaying dynamic report of a.out.analyze/dynamic/latest.AAACRaOId:
...
Displaying dynamic report of a.out.analyze/dynamic/latest.AAAQcayId:
LEAK 1: 1 allocation with total size of 4 bytes
main() + 0x5e <hello.c : 6>
2: #include <stdio.h>
4: int main()
5: {
6:=> int *i = malloc(sizeof(int));
8: int j = 0;
_start() + 0x71
...
Displaying dynamic report of a.out.analyze/dynamic/latest.AAAe5aWId:
LEAK 1: repeated, 1 blocks, 4 bytes
...
Displaying dynamic report of a.out.analyze/dynamic/latest.AAAlCaGId:
LEAK 1: repeated, 1 blocks, 4 bytes
...
Displaying dynamic report of a.out.analyze/dynamic/latest.AAAvCaWri:
LEAK 1: repeated, 1 blocks, 4 bytes
...
DISCOVER SUMMARY for a.out: 1 non-leak issues, 1 leak issues
unique errors : 1 (5 total)
unique warnings : 0 (0 total)
unique leaks : 1 (4 blocks, 16 bytes)
unique possible leaks : 0 (0 blocks, 0 bytes)
tests$ codean -d a.out
DYNAMIC report of a.out:
...
LEAK (Possible leak) 1: 1 allocation with total size of 4 bytes
main() + 0x5e <hello.c : 6>
2: #include <stdio.h>
4: int main()
5: {
6:=> int *i = malloc(sizeof(int));
8: int j = 0;
_start() + 0x71
DISCOVER SUMMARY for a.out: 1 non-leak issues, 1 leak issues
unique errors : 1 (1 total)
unique warnings : 0 (0 total)
unique leaks : 0 (0 blocks, 0 bytes)
unique possible leaks : 1 (1 blocks, 4 bytes)
保存测试套件的报告:
% codean --save --union -d --tag run1 a.out
a.out.analyze/dynamic/ 下的每个动态报告都保存在单独的文件中。
$ ls -l a.out.analyze/history/run1/ total 15 lrwxrwxrwx 1 demoUser demo 26 Sep 30 11:09 dynamic -> ./dynamic.latest.AAACRaOId -rw-r--r-- 1 demoUser demo 674 Sep 30 11:09 dynamic.latest.AAACRaOId -rw-r--r-- 1 demoUser demo 847 Sep 30 11:09 dynamic.latest.AAAQcayId -rw-r--r-- 1 demoUser demo 847 Sep 30 11:09 dynamic.latest.AAAe5aWId -rw-r--r-- 1 demoUser demo 847 Sep 30 11:09 dynamic.latest.AAAlCaGId -rw-r--r-- 1 demoUser demo 847 Sep 30 11:09 dynamic.latest.AAAvCaWri
比较测试套件的报告:
% codean --whatisnew --union -d --tag run1 a.out % codean --whatisfixed --union -d --tag run1 a.out
codean 命令将当前位于 a.out.analyze/dynamic/ 下的所有动态报告的新问题以及 a.out.analyze/history/run1/ 下的所有已保存动态报告的已修复问题分别显示为一组。下面是样例输出。
$ codean --whatisnew --union -d --tag run1 a.out
DYNAMIC report of a.out showing new issues:
New issues in a.out.analyze/dynamic/latest.AAARTaOxS:
ERROR 1 (ABR): reading memory beyond array bounds at address 0xfeffdef8 (4 bytes) on the stack at:
main() + 0x68 <hello.c : 11>
6: // int *i = malloc(sizeof(int));
7: int i[30];
9: int j = 0;
11:=> j = i[35];
13: return 0;
_start() + 0x71
New issues in a.out.analyze/dynamic/latest.AAATDaGxS:
ERROR 1 is a new, but repeated error. It was first seen as ERROR 1 in latest.AAARTaOxS.
New issues in a.out.analyze/dynamic/latest.AAArca4wS:
ERROR 1 is a new, but repeated error. It was first seen as ERROR 1 in latest.AAARTaOxS.
DISCOVER SUMMARY for a.out: 1 new non-leak issues, 0 new leak issues
new unique errors : 1 (3 total)
new unique warnings : 0 (0 total)
new unique leaks : 0 (0 blocks, 0 bytes)
new unique possible leaks : 0 (0 blocks, 0 bytes)
tests$ codean --whatisfixed --union -d --tag run1 a.out
DYNAMIC report of a.out showing fixed issues:
Fixed issues in a.out.analyze/history/run1/dynamic.latest.AAACRaOId:
ERROR 1 (UMR): accessing uninitialized data in "*i" at address 0x8090010 (4 bytes) on the heap at:
(Warning: Source files have changed. Source code shown below may not be accurate.)
main() + 0xe1 <hello.c : 10>
6: // int *i = malloc(sizeof(int));
7: int i[30];
9: int j = 0;
11: j = i[35];
_start() + 0x71
was allocated at (4 bytes):
main() + 0x5e <hello.c : 6>
2: #include <stdio.h>
4: int main()
5: {
6:=> // int *i = malloc(sizeof(int));
7: int i[30];
_start() + 0x71
Fixed issues in a.out.analyze/history/run1/dynamic.latest.AAAQcayId:
ERROR 1 is a fixed, but repeated error. It was first seen as ERROR 1 in dynamic.latest.AAACRaOId.
LEAK 1: 1 allocation with total size of 4 bytes
(Warning: Source files have changed. Source code shown below may not be accurate.)
main() + 0x5e <hello.c : 6>
2: #include <stdio.h>
4: int main()
5: {
6:=> // int *i = malloc(sizeof(int));
7: int i[30];
_start() + 0x71
Fixed issues in a.out.analyze/history/run1/dynamic.latest.AAAe5aWId:
ERROR 1 is a fixed, but repeated error. It was first seen as ERROR 1 in dynamic.latest.AAACRaOId.
LEAK 1 is a fixed, but repeated leak. It was first seen as LEAK 1 in dynamic.latest.AAAQcayId.
Fixed issues in a.out.analyze/history/run1/dynamic.latest.AAAlCaGId:
ERROR 1 is a fixed, but repeated error. It was first seen as ERROR 1 in dynamic.latest.AAACRaOId.
LEAK 1 is a fixed, but repeated leak. It was first seen as LEAK 1 in dynamic.latest.AAAQcayId.
Fixed issues in a.out.analyze/history/run1/dynamic.latest.AAAvCaWri:
ERROR 1 is a fixed, but repeated error. It was first seen as ERROR 1 in dynamic.latest.AAACRaOId.
LEAK 1 is a fixed, but repeated leak. It was first seen as LEAK 1 in dynamic.latest.AAAQcayId.
DISCOVER SUMMARY for a.out: 1 fixed non-leak issues, 1 fixed leak issues
fixed unique errors : 1 (5 total)
fixed unique warnings : 0 (0 total)
fixed unique leaks : 1 (4 blocks, 16 bytes)
fixed unique possible leaks : 0 (0 blocks, 0 bytes)