Как проанализировать утечку памяти из coredump
Я хотел бы проанализировать утечку памяти из анализа файла ядра.
Я написал пример кода, чтобы внедрить утечку памяти и создать файл ядра с помощью команды gcore.
#include <stdlib.h>
#include <unistd.h>
void fun()
{
int *ptr = new int(1234);
}
int main()
{
int i=0;
while(i++<2500)
{
fun();
}
sleep(360);
return 0;
}
Найти идентификатор процесса
ayadav@ajay-PC:~$ ps -aef |grep over
ajay 8735 6016 0 12:57 pts/2 00:00:00 ./over
ayadav 8739 4659 0 12:57 pts/10 00:00:00 grep over
и сгенерированное ядро
ayadav@ajay-PC:~$ sudo gcore 8735
[sudo] password for ayadav:
0x00007fbb7dda99a0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
Saved corefile core.8735
Я нашел общие шаблоны из базового файла, как показано ниже (как предложено для stackru другого потока. Есть ли способ определить, какая часть процесса использовала большую часть памяти, только просматривая сгенерированный базовый файл?)
ayadav@ajay-PC:~$ hexdump core.6015 | awk '{printf "%s%s%s%s\n%s%s%s%s\n", $5,$4,$3,$2,$9,$8,$7,$6}' | sort | uniq -c | sort -nr | head
6913 0000000000000000
2503 0000002100000000
2501 000004d200000000
786 0000000000007ffc
464
125 1ccbc4d000007ffc
92 1ca7ead000000000
91 0000000200007ffc
89 0000000100007ffc
80 0000000100000000
Под двумя адресами подозревается один
2503 0000002100000000
2501 000004d200000000
основной файл имеет повторяющиеся шаблоны
0003560 0000 0000 0021 0000 0000 0000 04d2 0000
0003570 0000 0000 0000 0000 0000 0000 0000 0000
0003580 0000 0000 0021 0000 0000 0000 04d2 0000
0003590 0000 0000 0000 0000 0000 0000 0000 0000
00035a0 0000 0000 0021 0000 0000 0000 04d2 0000
00035b0 0000 0000 0000 0000 0000 0000 0000 0000
00035c0 0000 0000 0021 0000 0000 0000 04d2 0000
00035d0 0000 0000 0000 0000 0000 0000 0000 0000
00035e0 0000 0000 0021 0000 0000 0000 04d2 0000
00035f0 0000 0000 0000 0000 0000 0000 0000 0000
0003600 0000 0000 0021 0000 0000 0000 04d2 0000
0003610 0000 0000 0000 0000 0000 0000 0000 0000
0003620 0000 0000 0021 0000 0000 0000 04d2 0000
0003630 0000 0000 0000 0000 0000 0000 0000 0000
0003640 0000 0000 0021 0000 0000 0000 04d2 0000
Но я не очень понимаю, как я могу получить к нему доступ с помощью команды, такой как GDB info address или x. Кто-нибудь может сказать, как я могу преобразовать символьную информацию из двоичного формата?
2 ответа
1 - Утечки памяти можно оценить с помощью дампа ядра. Я взял пример с ++:
class Base
{
public:
virtual void fun(){}
virtual void xyz(){}
virtual void lmv(){}
virtual void abc(){}
};
class Derived: public Base
{
public:
void fun(){}
void xyz(){}
void lmv(){}
void abc(){}
};
void fun()
{
Base *obj = new Derived();
}
int main()
{
for(int i = 0; i < 2500;i++)
{
fun();
}
sleep(3600);
return 0;
}
2 - Создал ядро с помощью команды gcore
3 - Поиск повторного шаблона из основного файла.
ayadav@ajay-PC:~$ hexdump core.10639 | awk '{printf "%s%s%s%s\n%s%s%s%s\n", $5,$4,$3,$2,$9,$8,$7,$6}' | sort | uniq -c | sort -nr | head
6685 0000000000000000
2502 0000002100000000
2500 004008d000000000
726 0000000000007eff
502
125 2e4314d000007eff
93 006010d000000000
81 0000000100007eff
80 0000000100000000
73 0000000000000001
0000002100000000
а также 004008d000000000
повторяются шаблоны
4 - Проверьте каждое слово, что с?
(gdb) info symbol ...
(gdb) x ...
пример:
(gdb) info symbol 0x4008d000
No symbol matches 0x4008d000.
(gdb) info symbol 0x4008d0
vtable for Derived + 16 in section .rodata of /home/ayadav/virtual
5 - Вероятно, наиболее часто встречающийся vtable должен относиться к утечке памяти, т.е. к производному vtable.
Примечание: я согласен, что анализ coredump не является наилучшей практикой для обнаружения утечки памяти. Утечку памяти можно обнаружить с помощью различных статических и динамических инструментов, таких как valgrind и т. Д.
Я не думаю, что есть способ определить, вызывает ли процесс утечку памяти или не смотрит непосредственно на дамп ядра. На самом деле, нет так называемой утечки памяти как таковой, мы не можем сделать этот комментарий, не зная намерения программистов написать код. Сказав это, вы можете получить представление, посмотрев на размер дампа ядра. Вы можете создать несколько дампов, скажем, один после первоначального запуска и один после длительного запуска, и если вы видите огромную разницу в размере, можно догадаться, что что-то идет не так. Но опять же, память может быть использована для продуктивных целей.
Для фактического анализа и отслеживания утечек памяти необходимо использовать такие инструменты, как memtrack, valgrind и т. Д., Чтобы добавить обертки поверх malloc и free, чтобы предоставить дополнительную информацию о каждом alloc и free.
Обновить:
Поскольку вы ищете анализ в шестнадцатеричном формате, вот что я вижу: каждая ваша строка состоит из 16 байтов и повторяется в двух строках. Это 32 байта куска. 0x4D2 - это 1234 в десятичном виде. Итак, ваши данные там. Вполне возможно, что ваш один выделенный блок составляет 32 байта. Проверяйте и печатайте адрес в шестнадцатеричном формате после каждого "new()" и сравнивайте, чтобы увидеть, наблюдаете ли вы разрыв в 32 байта, а затем он объясняет это.