FastNetMon

Monday 8 March 2010

Как найти memory leak в С / С++ приложении? Valgrind!

Ставим:
apt-get install valgrind -y


Создаем файл с намеренным мемликом: memleak.c
#include <stdio.h>
#include <stdlib.h>

int main() {
char* memory_leak = (char*)malloc(1000 * sizeof(char));

return 0;
}


Компилруем:

gcc memleak.c


Натравливаем на программу Valgrind:

valgrind ./a.out
==20343== Memcheck, a memory error detector.
==20343== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==20343== Using LibVEX rev 1854, a library for dynamic binary translation.
==20343== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==20343== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework.
==20343== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==20343== For more details, rerun with: -v
==20343==
==20343==
==20343== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)
==20343== malloc/free: in use at exit: 1,000 bytes in 1 blocks.
==20343== malloc/free: 1 allocs, 0 frees, 1,000 bytes allocated.
==20343== For counts of detected errors, rerun with: -v
==20343== searching for pointers to 1 not-freed blocks.
==20343== checked 74,896 bytes.
==20343==
==20343== LEAK SUMMARY:
==20343== definitely lost: 1,000 bytes in 1 blocks.
==20343== possibly lost: 0 bytes in 0 blocks.
==20343== still reachable: 0 bytes in 0 blocks.
==20343== suppressed: 0 bytes in 0 blocks.
==20343== Rerun with --leak-check=full to see details of leaked memory.


Ну что же, мемлик успешно найден: definitely lost: 1,000 bytes in 1 blocks.

Теперь попробуем найти источник мемлика:

valgrind --leak-check=full ./a.out
==21746== Memcheck, a memory error detector.
==21746== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==21746== Using LibVEX rev 1854, a library for dynamic binary translation.
==21746== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==21746== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework.
==21746== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==21746== For more details, rerun with: -v
==21746==
==21746==
==21746== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)
==21746== malloc/free: in use at exit: 1,000 bytes in 1 blocks.
==21746== malloc/free: 1 allocs, 0 frees, 1,000 bytes allocated.
==21746== For counts of detected errors, rerun with: -v
==21746== searching for pointers to 1 not-freed blocks.
==21746== checked 74,896 bytes.
==21746==
==21746== 1,000 bytes in 1 blocks are definitely lost in loss record 1 of 1
==21746== at 0x4C2260E: malloc (vg_replace_malloc.c:207)
==21746== by 0x4004DD: main (in /root/a.out)
==21746==
==21746== LEAK SUMMARY:
==21746== definitely lost: 1,000 bytes in 1 blocks.
==21746== possibly lost: 0 bytes in 0 blocks.
==21746== still reachable: 0 bytes in 0 blocks.
==21746== suppressed: 0 bytes in 0 blocks.



Теперь более ясно - потери памяти идут в вызове malloc из функции malloc. Но где именно - неясно.

Для того, чтобы узнать строку, на которой идут потери, необходимо собрать программу с отладочной информацией:
gcc -g memleak.c


Повторно запускаем Valgrind:

valgrind --leak-check=full ./a.out
==22354== Memcheck, a memory error detector.
==22354== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==22354== Using LibVEX rev 1854, a library for dynamic binary translation.
==22354== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==22354== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework.
==22354== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==22354== For more details, rerun with: -v
==22354==
==22354==
==22354== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 1)
==22354== malloc/free: in use at exit: 1,000 bytes in 1 blocks.
==22354== malloc/free: 1 allocs, 0 frees, 1,000 bytes allocated.
==22354== For counts of detected errors, rerun with: -v
==22354== searching for pointers to 1 not-freed blocks.
==22354== checked 74,896 bytes.
==22354==
==22354== 1,000 bytes in 1 blocks are definitely lost in loss record 1 of 1
==22354== at 0x4C2260E: malloc (vg_replace_malloc.c:207)
==22354== by 0x4004DD: main (memleak.c:5)
==22354==
==22354== LEAK SUMMARY:
==22354== definitely lost: 1,000 bytes in 1 blocks.
==22354== possibly lost: 0 bytes in 0 blocks.
==22354== still reachable: 0 bytes in 0 blocks.
==22354== suppressed: 0 bytes in 0 blocks.



И вуаля, утечка памяти на 5й строке нашего файла, как раз там, где мы ее осознанно сделали :)

No comments :

Post a Comment

Note: only a member of this blog may post a comment.