这是老张找出来的,一直引擎都有一个10M左右的内存不可用,一直没有得到解决,老张前天晚上hacking了一晚上,搞定了。也难为老张了,一个windows程序员,使用valgrind来调试linux程序;-)
查看内存泄露当然还得是valgrind了,关于使用可以查看之前的文章。
过程:
apt-get source unrar-free的代码,编译之后,找一个2.9格式的进行测试。
wangyao@wangyao-laptop:~/unrar/unrar-free-0.0.1+cvs20070515/src$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./unrar -x t.rar
==23368== Memcheck, a memory error detector.
==23368== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==23368== Using LibVEX rev 1804, a library for dynamic binary translation.
==23368== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==23368== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework.
==23368== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==23368== For more details, rerun with: -v
==23368==
unrar 0.0.1 Copyright (C) 2004 Ben Asselstine, Jeroen Dekkers
Extracting from /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/t.rar
==23368== Use of uninitialised value of size 4
==23368== at 0x804B173: CalcCRC32 (unrarlib.c:2168)
==23368== by 0x804CAA6: ReadHeader (unrarlib.c:618)
==23368== by 0x804CE50: ReadBlock (unrarlib.c:506)
==23368== by 0x804D5D3: urarlib_list (unrarlib.c:389)
==23368== by 0x80496F2: unrar_extract (unrar.c:420)
==23368== by 0x8049E44: main (unrar.c:556)
==23368==
==23368== Conditional jump or move depends on uninitialised value(s)
==23368== at 0x804CA88: ReadHeader (unrarlib.c:617)
==23368== by 0x804CE50: ReadBlock (unrarlib.c:506)
==23368== by 0x804D5D3: urarlib_list (unrarlib.c:389)
==23368== by 0x80496F2: unrar_extract (unrar.c:420)
==23368== by 0x8049E44: main (unrar.c:556)
==23368==
==23368== Use of uninitialised value of size 4
==23368== at 0x804B173: CalcCRC32 (unrarlib.c:2168)
==23368== by 0x804C92A: ReadHeader (unrarlib.c:626)
==23368== by 0x804CE50: ReadBlock (unrarlib.c:506)
==23368== by 0x804D5D3: urarlib_list (unrarlib.c:389)
==23368== by 0x80496F2: unrar_extract (unrar.c:420)
==23368== by 0x8049E44: main (unrar.c:556)
==23368==
==23368== Conditional jump or move depends on uninitialised value(s)
==23368== at 0x804CDAD: ReadBlock (unrarlib.c:509)
==23368== by 0x804D5D3: urarlib_list (unrarlib.c:389)
==23368== by 0x80496F2: unrar_extract (unrar.c:420)
==23368== by 0x8049E44: main (unrar.c:556)
Extracting 7C.tmp Failed
1 Failed
==23368==
==23368== ERROR SUMMARY: 55 errors from 4 contexts (suppressed: 11 from 1)
==23368== malloc/free: in use at exit: 4,529,194 bytes in 6 blocks.
==23368== malloc/free: 27 allocs, 21 frees, 6,663,987 bytes allocated.
==23368== For counts of detected errors, rerun with: -v
==23368== searching for pointers to 6 not-freed blocks.
==23368== checked 122,192 bytes.
==23368==
==23368==
==23368== 1 bytes in 1 blocks are still reachable in loss record 1 of 5
==23368== at 0x4021BDE: calloc (vg_replace_malloc.c:397)
==23368== by 0x804D7AA: urarlib_get (unrarlib.c:307)
==23368== by 0x8049561: unrar_extract_file (unrar.c:343)
==23368== by 0x804987D: unrar_extract (unrar.c:482)
==23368== by 0x8049E44: main (unrar.c:556)
==23368==
==23368==
==23368== 7 bytes in 1 blocks are still reachable in loss record 2 of 5
==23368== at 0x4022B8E: realloc (vg_replace_malloc.c:429)
==23368== by 0x804D011: ReadBlock (unrarlib.c:538)
==23368== by 0x804D2BE: ExtrFile (unrarlib.c:716)
==23368== by 0x804D783: urarlib_get (unrarlib.c:303)
==23368== by 0x8049561: unrar_extract_file (unrar.c:343)
==23368== by 0x804987D: unrar_extract (unrar.c:482)
==23368== by 0x8049E44: main (unrar.c:556)
==23368==
==23368==
==23368== 66 bytes in 2 blocks are still reachable in loss record 3 of 5
==23368== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==23368== by 0x40AAFCF: strdup (in /lib/tls/i686/cmov/libc-2.7.so)
==23368== by 0x804D722: urarlib_get (unrarlib.c:282)
==23368== by 0x8049561: unrar_extract_file (unrar.c:343)
==23368== by 0x804987D: unrar_extract (unrar.c:482)
==23368== by 0x8049E44: main (unrar.c:556)
==23368==
==23368==
==23368== 262,148 bytes in 1 blocks are still reachable in loss record 4 of 5
==23368== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==23368== by 0x8054A32: rarvm_init (unrarvm.c:193)
==23368== by 0x804F14F: unpack_init_data (unrar29.c:1126)
==23368== by 0x804F9E2: rar_unpack29 (unrar29.c:1165)
==23368== by 0x8056678: Unpack29 (unpack29.c:67)
==23368== by 0x804D406: ExtrFile (unrarlib.c:788)
==23368== by 0x804D783: urarlib_get (unrarlib.c:303)
==23368== by 0x8049561: unrar_extract_file (unrar.c:343)
==23368== by 0x804987D: unrar_extract (unrar.c:482)
==23368== by 0x8049E44: main (unrar.c:556)
==23368==
==23368==
==23368== 4,266,972 bytes in 1 blocks are still reachable in loss record 5 of 5
==23368== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==23368== by 0x805672C: Unpack29 (unpack29.c:52)
==23368== by 0x804D406: ExtrFile (unrarlib.c:788)
==23368== by 0x804D783: urarlib_get (unrarlib.c:303)
==23368== by 0x8049561: unrar_extract_file (unrar.c:343)
==23368== by 0x804987D: unrar_extract (unrar.c:482)
==23368== by 0x8049E44: main (unrar.c:556)
==23368==
==23368== LEAK SUMMARY:
==23368== definitely lost: 0 bytes in 0 blocks.
==23368== possibly lost: 0 bytes in 0 blocks.
==23368== still reachable: 4,529,194 bytes in 6 blocks.
==23368== suppressed: 0 bytes in 0 blocks.
发现在程序结束之前还有一部分内存reachable。
为了方便测试,我们可以利用unrar-free的接口,写一个简单的测试程序:
#include "unrarlib.h"
#include "stdio.h"
unsigned char buf[1024000];
int main()
{
FILE* fp;
int i,n,j;
unsigned char* databuf = 0;
int size = 0;
for(i=0;i<20;i++)
{
ArchiveList_struct list = {0};
ArchiveList_struct *listptr = 0;
n = urarlib_list ("./t.rar", &list.next);
listptr = list.next;
for (j = 0; j < n; j++, listptr = listptr->next)
{
puts(listptr->item.Name);
urarlib_get (&databuf,&size,listptr->item.Name,"./t.rar","");
fp = fopen("t.db","wb");
fwrite(databuf,1,size,fp);
fclose(fp);
free(databuf);
}
urarlib_freelist (list.next);
}
printf("%d , %x \r\n", size,databuf);
getchar();
return 0;
}
运行测试程序:
==15189==
==15189== ERROR SUMMARY: 2180 errors from 26 contexts (suppressed: 11 from 1)
==15189== malloc/free: in use at exit: 9,509,955 bytes in 25 blocks.
==15189== malloc/free: 341 allocs, 316 frees, 52,033,452 bytes allocated.
==15189== For counts of detected errors, rerun with: -v
==15189== searching for pointers to 25 not-freed blocks.
==15189== checked 1,150,188 bytes.
==15189==
==15189==
==15189== 7 bytes in 1 blocks are still reachable in loss record 1 of 6
==15189== at 0x4022B8E: realloc (vg_replace_malloc.c:429)
==15189== by 0x8051EFA: ReadBlock (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x805267E: ExtrFile (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8051928: urarlib_get (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8048F3D: main (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189==
==15189==
==15189== 16 bytes in 3 blocks are still reachable in loss record 2 of 6
==15189== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==15189== by 0x40AAFCF: strdup (in /lib/tls/i686/cmov/libc-2.7.so)
==15189== by 0x80518CD: urarlib_get (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8048F3D: main (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189==
==15189==
==15189== 262,148 bytes in 1 blocks are still reachable in loss record 3 of 6
==15189== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==15189== by 0x8058213: rarvm_init (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x804F965: unpack_init_data (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x804FC28: rar_unpack29 (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8049D3F: Unpack29 (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8052825: ExtrFile (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8051928: urarlib_get (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8048F3D: main (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189==
==15189==
==15189== 2,097,184 bytes in 8 blocks are possibly lost in loss record 4 of 6
==15189== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==15189== by 0x8058213: rarvm_init (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x804F965: unpack_init_data (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x804FC28: rar_unpack29 (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8049D3F: Unpack29 (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8052825: ExtrFile (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8051928: urarlib_get (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8048F3D: main (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189==
==15189==
==15189== 2,883,628 bytes in 11 blocks are definitely lost in loss record 5 of 6
==15189== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==15189== by 0x8058213: rarvm_init (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x804F965: unpack_init_data (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x804FC28: rar_unpack29 (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8049D3F: Unpack29 (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8052825: ExtrFile (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8051928: urarlib_get (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8048F3D: main (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189==
==15189==
==15189== 4,266,972 bytes in 1 blocks are still reachable in loss record 6 of 6
==15189== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==15189== by 0x8049C3A: Unpack29 (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8052825: ExtrFile (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8051928: urarlib_get (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189== by 0x8048F3D: main (in /home/wangyao/unrar/unrar-free-0.0.1+cvs20070515/src/test)
==15189==
==15189== LEAK SUMMARY:
==15189== definitely lost: 2,883,628 bytes in 11 blocks.
==15189== possibly lost: 2,097,184 bytes in 8 blocks.
==15189== still reachable: 4,529,143 bytes in 6 blocks.
==15189== suppressed: 0 bytes in 0 blocks.
内存泄露的地方是一样子的,只不过我们已经简化了调用的层数而已。
最终修改:
在Unpack29()最后加上:
/*By LaoZhang*/
rarvm_free(&unpack_data->rarvm_data);
free(unpack_data);
unpack_data = 0;
在urarlib_get()最后加上:
/*By LaoZhang*/
if (ArgName) free(ArgName);
if (ArcName) free(ArcName);
if (Password) free(Password);
if (ArcFileName) free(ArcFileName);
ArgName = ArcName = Password = ArcFileName = 0;
修改完后再做测试:
wangyao@wangyao-laptop:~/unrar/unrar-free-ok/src$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./unrar -x t.rar
==23847== Memcheck, a memory error detector.
==23847== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==23847== Using LibVEX rev 1804, a library for dynamic binary translation.
==23847== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==23847== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework.
==23847== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==23847== For more details, rerun with: -v
==23847==
unrar 0.0.1 Copyright (C) 2004 Ben Asselstine, Jeroen Dekkers
Extracting from /home/wangyao/unrar/unrar-free-ok/src/t.rar
==23847== Use of uninitialised value of size 4
==23847== at 0x804B173: CalcCRC32 (unrarlib.c:2145)
==23847== by 0x804CAA6: ReadHeader (unrarlib.c:610)
==23847== by 0x804CE50: ReadBlock (unrarlib.c:490)
==23847== by 0x804D5E3: urarlib_list (unrarlib.c:372)
==23847== by 0x80496F2: unrar_extract (unrar.c:420)
==23847== by 0x8049E44: main (unrar.c:556)
==23847==
==23847== Conditional jump or move depends on uninitialised value(s)
==23847== at 0x804CA88: ReadHeader (unrarlib.c:608)
==23847== by 0x804CE50: ReadBlock (unrarlib.c:490)
==23847== by 0x804D5E3: urarlib_list (unrarlib.c:372)
==23847== by 0x80496F2: unrar_extract (unrar.c:420)
==23847== by 0x8049E44: main (unrar.c:556)
==23847==
==23847== Use of uninitialised value of size 4
==23847== at 0x804B173: CalcCRC32 (unrarlib.c:2145)
==23847== by 0x804C92A: ReadHeader (unrarlib.c:620)
==23847== by 0x804CE50: ReadBlock (unrarlib.c:490)
==23847== by 0x804D5E3: urarlib_list (unrarlib.c:372)
==23847== by 0x80496F2: unrar_extract (unrar.c:420)
==23847== by 0x8049E44: main (unrar.c:556)
==23847==
==23847== Conditional jump or move depends on uninitialised value(s)
==23847== at 0x804CDAD: ReadBlock (unrarlib.c:493)
==23847== by 0x804D5E3: urarlib_list (unrarlib.c:372)
==23847== by 0x80496F2: unrar_extract (unrar.c:420)
==23847== by 0x8049E44: main (unrar.c:556)
Extracting 7C.tmp OK
All OK
==23847==
==23847== ERROR SUMMARY: 55 errors from 4 contexts (suppressed: 11 from 1)
==23847== malloc/free: in use at exit: 0 bytes in 0 blocks.
==23847== malloc/free: 27 allocs, 27 frees, 6,663,957 bytes allocated.
==23847== For counts of detected errors, rerun with: -v
==23847== All heap blocks were freed -- no leaks are possible.
阅读(2518) | 评论(0) | 转发(0) |