3

在我寻找 C++ 代码中特别持久的内存泄漏的过程中,我决定将所有分配写入以下格式的日志文件:

<alloc|free> <address> <size> <UNIQUE-ID> <file> <line number>

这给了我,例如:

alloc 232108     60   405766 file1.cpp (3572)
free  232128     60   405766
alloc 232108     60   405767 file1.cpp (3572)
free  232128     60   405767
alloc 7a3620  12516   405768 file2.cpp (11435)
free  7a3640  12516   405768
alloc 2306c8    256   405769 file3.cpp (3646)
alloc 746160   6144   405770 file3.cpp (20462)
alloc 6f3528   2048   405771 file4.h (153)
alloc 6aca50    128   405772 file4.h (153)
alloc 632ec8    128   405773 file4.h (153)
alloc 732ff0    128   405774 file4.h (153)
free  746180   6144   405770
free  632ee8    128   405773
alloc 6a7610   2972   405778 this_alloc_has_no_counterpart.cpp (123)
free  6aca70    128   405772
free  733010    128   405774
free  6f3548   2048   405771
alloc 6a7610   2972   405775 file3.cpp (18043)
alloc 7a3620  12316   405776 file5.cpp (474)
alloc 631e00    256   405777 file3.cpp (18059)
free  7a3640  12316   405776
free  6a7630   2972   405775
free  631e20    256   405777
free  2306e8    256   405769

我试图将 everyalloc与 a匹配free,只留下allocs 没有free对应物,例如 allocation number 405778

我能想出的是以下shell脚本:

#!/bin/sh
grep "^alloc" test.txt | while read line
do
    alloc_nr=`echo $line | awk '{ print $4 }'`  # arg4 = allocation number
    echo "Processing $alloc_nr"
    sed -i "/ ${alloc_nr}/{//d}" test.txt
done

正如您可能已经猜到的那样,在一个大约 144000 秒的 25MB 文件上,这非常慢(即每秒 2 个循环)alloc,因为我sed以一种非常低效的方式使用。

如果有人可以在正确的方向上推动我如何在不花费三个小时的情况下实现这一目标,我们将不胜感激。

4

2 回答 2

3
awk '/^alloc/ { a[$4]=$0; }
     /^free/ { delete a[$4]; }
     END { for (i in a) {print a[i]; }' test.txt
于 2012-12-20T10:03:22.577 回答
3

似乎您只想要 ID 而不是整行:

$ awk '{print $4}' file | sort | uniq -u
405778

awk '{print $4}'仅打印 ID 列。

sort对列进行排序。

uniq -u仅显示唯一 ID。

编辑:

管道grep -f - file匹配整行,无需循环:

$ awk '{print $4}' file | sort | uniq -u | grep -f - file
alloc 6a7610   2972   405778 this_alloc_has_no_counterpart.cpp (123)

grep -f匹配文件中的模式并-表示使用stdin.

于 2012-12-20T10:05:02.943 回答