您可以将 –-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)