7.2.2. Использование mtrace() для отслеживания распределений памяти

7.2.2. Использование mtrace() для отслеживания распределений памяти

Один из простых способов нахождения всех утечек памяти в программе предусматривает регистрацию всех вызовов malloc() и free(). По окончании программы очень легко сопоставить блоки, распределенные через malloc(), с точками, где они были освобождены с помощью free() или сообщить об ошибке, если для какого-то блока free() не вызывалась.

В отличие от mcheck(), в mtrace() нет соответствующей библиотеки для компоновки. Это не проблема, поскольку трассировку можно осуществлять в gdb. Однако для включения трассировки с помощью mtrace() должна быть установлена переменная окружения MALLOC_TRACE в допустимое имя файла; это может быть либо имя существующего файла, в который процесс может вести запись, либо имя нового файла, который процесс создаст и будет в него записывать.

$ MALLOC_TRACE=mtrace.log gdb broken

...

(gdb) breakmain

Breakpoint 1 at 0x80483f4: filebroken.c, line 14.

(gdb) command 1

Type commands for when Breakpoint 1 is hit, one per line.

End with a line saying just "end".

>call mtrace()

>continue

>end

(gdb) run

Starting program: /usr/src/lad/code/broken

Breakpoint 1, main() at broken.с:47

47 return broken();

$1 = 0

1: 12345

2: 12345678

3: 12345678

4: 12345

5: 12345

6: 12345

7: 12345

Program exited normally.

Программа завершена нормально.

 (gdb) quit

$ ls -l mtrace.log

-rw-rw-r-- 1 ewt ewt 220 Dec 27 23:41 mtrace.log

$ mtrace ./broken mtrace.log

Memory not freed:

He освобождена память:

----------------------

   Address   Size Caller

     Адрес Размер Место вызова

0x09211378    0x5 at /usr/src/lad/code/broken.с:20

Обратите внимание, что программа mtrace точно обнаружила утечку памяти. Также она может найти факт освобождения с помощью free() памяти, которая ранее не распределялась, если этот факт будет зафиксирован в журнальном файле, но на практике так не происходит, поскольку в этом случае программа немедленно аварийно завершается.