Ключевые слова:gcc, memory, debug, (найти похожие документы)
From: "Valentin Nechayev" <netch@segfault.kiev.ua>
Newsgroups: fido7.ru.unix.prog
Subject: Отслеживание проблем с распределением памяти при помощи YAMD
Date: Mon, 5 May 2003 07:06:34 +0000 (UTC)
YAMD. Рассказ от Aleksey Cheusov
Поскольку valgrind у меня иногда вылетает, я использую вместо него
YAMD+efence. Но хочу сказать, что YAMD не обязательно самый продвинутый.
Просто мне в своё время надоело искать и я остановился на том,
что меня устраивает и мои поиски закончились.
YAMD:
- Он маленький и в случае чего нетрудно будет разобраться
где и что не так.
- Нет необходимости в перекмпиляции/линковки программ для вылавливания
багов при работе с памятью по крайней мере на платформах, где есть
LD_PRELOAD (ELF).
- В нем несколько программ, но полезная ДЛЯ МЕНЯ только одна. run-yamd
Пример:
run-yamd -o /tmp/dictd.mem ./dictd --test apple
Это дело вываливает мне простыню типа
<бесполезная шапка>
INFO: Normal allocation of this block
Address 0x40023fd4, size 44
Allocated by malloc at
/lib/libc.so.6(malloc+0x2f)[0x400c9eaf]
./dictd(strcpy+0xcbf7)[0x8057133]
./dictd(strcpy+0xcda8)[0x80572e4]
./dictd(strcpy+0xce4c)[0x8057388]
./dictd(strcpy+0x10c1f)[0x805b15b]
./dictd(strcpy+0x10c44)[0x805b180]
./dictd(strcpy+0x108fb)[0x805ae37]
./dictd(strcpy+0x1a36)[0x804bf72]
./dictd(strcpy+0x1ca2)[0x804c1de]
/lib/libc.so.6(__libc_start_main+0xbe)[0x400737ee]
./dictd(strcpy+0x35)[0x804a571]
INFO: Normal deallocation of this block
Address 0x4018eff0, size 16
Allocated by malloc at
/lib/libc.so.6(malloc+0x2f)[0x400c9eaf]
./dictd(strcpy+0xcbf7)[0x8057133]
./dictd(strcpy+0xcf64)[0x80574a0]
./dictd(strcpy+0xd0cc)[0x8057608]
./dictd(strcpy+0x10125)[0x805a661]
./dictd(strcpy+0x10919)[0x805ae55]
./dictd(strcpy+0x1a36)[0x804bf72]
./dictd(strcpy+0x1ca2)[0x804c1de]
/lib/libc.so.6(__libc_start_main+0xbe)[0x400737ee]
./dictd(strcpy+0x35)[0x804a571]
Freed by free at
/lib/libc.so.6(__libc_free+0x2f)[0x400ca92f]
./dictd(strcpy+0xccba)[0x80571f6]
./dictd(strcpy+0xce90)[0x80573cc]
./dictd(strcpy+0xd063)[0x805759f]
./dictd(strcpy+0x10125)[0x805a661]
./dictd(strcpy+0x1092b)[0x805ae67]
./dictd(strcpy+0x1a36)[0x804bf72]
./dictd(strcpy+0x1ca2)[0x804c1de]
/lib/libc.so.6(__libc_start_main+0xbe)[0x400737ee]
./dictd(strcpy+0x35)[0x804a571]
WARNING: Free of null pointer
At
/lib/libc.so.6(__libc_free+0x2f)[0x400ca92f]
/lib/libc.so.6(_dl_close+0x57b)[0x4015682b]
/lib/libdl.so.2(dlopen+0x6b)[0x4017e4cb]
??:0(??)[0x4000b5a0]
/lib/libdl.so.2(dlerror+0x290)[0x4017e8b0]
/lib/libdl.so.2(dlclose+0x21)[0x4017e4f1]
/usr/lib/libltdl.so.3(lt_dlseterror+0x302)[0x4002bb82]
/usr/lib/libltdl.so.3(lt_dlclose+0xb9)[0x4002e5a9]
./dictd(strcpy+0xb7f6)[0x8055d32]
./dictd(strcpy+0x1119)[0x804b655]
./dictd(strcpy+0x1333)[0x804b86f]
./dictd(strcpy+0x2505)[0x804ca41]
/lib/libc.so.6(__libc_start_main+0xbe)[0x400737ee]
./dictd(strcpy+0x35)[0x804a571]
Attempt to free null pointer
WARNING: Memory leak
Address 0x42770fe4, size 28
Allocated by malloc at
/lib/libc.so.6(malloc+0x2f)[0x400c9eaf]
/lib/libc.so.6(textdomain+0x62a)[0x40081f4a]
/lib/libc.so.6(textdomain+0x79e)[0x400820be]
/lib/libc.so.6(textdomain+0x79e)[0x400820be]
/lib/libc.so.6(ngettext+0x217)[0x40080b07]
/lib/libc.so.6(gettext+0x845)[0x4007fd55]
/lib/libc.so.6(__dcgettext+0x2d)[0x4007f4cd]
/lib/libc.so.6(__strerror_r+0x132)[0x400cf8b2]
/lib/libc.so.6(strerror+0x2b)[0x400cf76b]
/lib/libdl.so.2(dlerror+0xbf)[0x4017e6df]
/usr/lib/libltdl.so.3(lt_dlseterror+0x395)[0x4002bc15]
/usr/lib/libltdl.so.3(lt_dlsym+0x30f)[0x4002e96f]
./dictd(strcpy+0xb4f6)[0x8055a32]
./dictd(strcpy+0xb6c0)[0x8055bfc]
./dictd(strcpy+0xeea)[0x804b426]
./dictd(strcpy+0xecf2)[0x805922e]
./dictd(strcpy+0x12e5)[0x804b821]
./dictd(strcpy+0x24b4)[0x804c9f0]
/lib/libc.so.6(__libc_start_main+0xbe)[0x400737ee]
./dictd(strcpy+0x35)[0x804a571]
WARNING: Total memory leaks:
2008 unfreed allocations totaling 91268 bytes
*** Finished at Wed Dec 4 12:36:04 2002
Allocated a grand total of 418487 bytes
2410 allocations
Average of 173 bytes per allocation
Max bytes allocated at one time: 398226
29176 K alloced internally / 11744 K mapped now / 10972 K max
Virtual program size is 32592 K
End.
- Выше только адреса. Для получения по ним имена функций со строками
нужно воспользоваться do-syms:
do-syms ./dictd < /tmp/dictd.mem > /tmp/dictd.mem2
Получаем что-=то вроде
INFO: Normal allocation of this block
Address 0x40023fd4, size 44
Allocated by malloc at
/lib/libc.so.6(malloc+0x2f) ??:0
./dictd(strcpy+0xcbf7) /shared/cheusov/prjs/dictd1/libmaa/xmalloc.c:40
./dictd(strcpy+0xcda8) /shared/cheusov/prjs/dictd1/libmaa/hash.c:80
./dictd(strcpy+0xce4c) /shared/cheusov/prjs/dictd1/libmaa/hash.c:127
./dictd(strcpy+0x10c1f) /shared/cheusov/prjs/dictd1/libmaa/timer.c:47
./dictd(strcpy+0x10c44) /shared/cheusov/prjs/dictd1/libmaa/timer.c:57
./dictd(strcpy+0x108fb) /shared/cheusov/prjs/dictd1/libmaa/maa.c:36
./dictd(strcpy+0x1a36) /shared/cheusov/prjs/dictd1/dictd.c:925
./dictd(strcpy+0x1ca2) /shared/cheusov/prjs/dictd1/dictd.c:1064
/lib/libc.so.6(__libc_start_main+0xbe) ??:0
./dictd(strcpy+0x35) ??:0
do-syms использует addr2line.
НО Я ПРЕДУПРЕЖДАЮ, ЧТО РОДНАЯ ВЕРСИЯ do-syms на Linux НЕ РАБОТАЕТ.
Поэтому я написал свою на shell:
http://www.mova.org/~cheusov/pub/do-syms
Если программа слинкована динамически, то addr2line
обламывается. Можно прикрутить к do-syms gdb с breakpoint на _init
и эти проблемы решаются. В ближайшее время этим займусь.
- ВСю необходимую мне статистику я лично собираю скриптами.
Memory leaks собираю, например,
awk '/Memory leak/, /^$/' < /tmp/dictd.mem2
Опять же скриптами можно отсеить memory leaks системных функций,
например setlocale в glibc2.2.
Вот собственно и все.
Функциональности - минимум. Все пишется скриптами.