файлы дампа ядра в Linux: как получить информацию об открытых файлах? - PullRequest
28 голосов
/ 12 сентября 2008

У меня есть файл дампа ядра из процесса, который, вероятно, имеет утечку дескриптора файла (он открывает файлы и сокеты, но, очевидно, иногда забывает закрыть некоторые из них). Есть ли способ узнать, какие файлы и сокеты процесс открыл перед сбоем? Я не могу легко воспроизвести сбой, поэтому анализ файла ядра, похоже, является единственным способом получить подсказку об ошибке.

Ответы [ 8 ]

10 голосов
/ 15 сентября 2008

Если у вас есть файл ядра и вы скомпилировали программу с параметрами отладки (-g), вы можете увидеть, куда было выгружено ядро:

$ gcc -g -o something something.c
$ ./something
Segmentation fault (core dumped)
$ gdb something core

Вы можете использовать это, чтобы сделать некоторую посмертную отладку. Несколько команд GDB: br печатает стек, fr переходит на заданный кадр стека (см. Вывод br).

Теперь, если вы хотите увидеть, какие файлы открываются при ошибке сегментации, просто обработайте сигнал SIGSEGV, а в обработчике просто сбросьте содержимое каталога / proc / PID / fd (то есть с системой ('ls - l / proc / PID / fs ') или execv).

Имея эту информацию под рукой, вы можете легко найти причину сбоя, какие файлы открыты и связаны ли сбой и утечка файлового дескриптора.

4 голосов
/ 12 сентября 2008

Лучше всего установить обработчик сигнала для любого сигнала, вызывающего сбой вашей программы (SIGSEGV и т. Д.).

Затем в обработчике сигналов проверьте / proc / self / fd и сохраните содержимое в файл. Вот пример того, что вы можете увидеть:

Anderson cxc # ls -l  /proc/8247/fd
total 0
lrwx------ 1 root root 64 Sep 12 06:05 0 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 12 06:05 1 -> /dev/pts/0
lrwx------ 1 root root 64 Sep 12 06:05 10 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Sep 12 06:05 11 -> socket:[124061]
lrwx------ 1 root root 64 Sep 12 06:05 12 -> socket:[124063]
lrwx------ 1 root root 64 Sep 12 06:05 13 -> socket:[124064]
lrwx------ 1 root root 64 Sep 12 06:05 14 -> /dev/driver0
lr-x------ 1 root root 64 Sep 12 06:05 16 -> /temp/app/whatever.tar.gz
lr-x------ 1 root root 64 Sep 12 06:05 17 -> /dev/urandom

Затем вы можете вернуться из обработчика сигналов и получить дамп ядра как обычно.

3 голосов
/ 19 декабря 2014

Один из способов перейти к этой информации - просто запустить strings в основном файле. Например, когда я недавно запускал файл на ядре, из-за длины папок я получал список усеченных аргументов. Я знал, что мой запуск откроет файлы из моего домашнего каталога, поэтому я просто запустил:

strings core.14930|grep jodie

Но это тот случай, когда у меня были иголка и стог сена.

3 голосов
/ 12 сентября 2008

Вы можете попробовать использовать strace для просмотра вызовов open, socket и close, которые делает программа.

Редактировать: я не думаю, что вы можете получить информацию из ядра; самое большее, он где-то будет иметь файловые дескрипторы, но это все равно не даст вам фактический файл / сокет. (Предполагая, что вы можете отличить открытые и закрытые файловые дескрипторы, в которых я тоже сомневаюсь.)

2 голосов
/ 16 сентября 2015

Недавно, во время устранения ошибок и анализа ошибок, мой клиент предоставил мне coredump, который был сгенерирован в его файловой системе, и он вышел из станции, чтобы быстро просмотреть файл и прочитать его содержимое, я использовал команду

строки core.67545> coredump.txt и позже я смог открыть файл в редакторе файлов.

2 голосов
/ 12 сентября 2008

Если программа забыла закрыть эти ресурсы, это может произойти из-за следующего:

fd = open("/tmp/foo",O_CREAT);
//do stuff
fd = open("/tmp/bar",O_CREAT); //Oops, forgot to close(fd)

теперь у меня не будет файлового дескриптора для foo в памяти.

Если этого не произошло, вы могли бы найти номер дескриптора файла, но, опять же, это не очень полезно, потому что они постоянно меняются, к тому времени, как вы приступите к отладке, вы не будете знать, какой файл это на самом деле означало в то время.

Я действительно думаю, что вы должны отладить это вживую, с strace, lsof и друзьями.

Если есть способ сделать это из дампа памяти, я тоже хочу это знать: -)

1 голос
/ 12 сентября 2008

Дамп ядра - это копия памяти, к которой у процесса был доступ при сбое. В зависимости от того, как происходит утечка, она может потерять ссылку на рукоятки, поэтому может оказаться бесполезной.

lsof перечисляет все открытые в настоящее время файлы в системе, вы можете проверить его вывод, чтобы найти утечки сокетов или файлов. Да, вам нужно запустить процесс. Вы можете запустить его с определенным именем пользователя, чтобы легко определить, какие файлы открыты в процессе, который вы отлаживаете.

Надеюсь, у кого-то есть информация получше: -)

0 голосов
/ 12 сентября 2008

Еще один способ узнать, какие файлы открыты процессом - опять же, только во время выполнения - ищет в / proc / PID / fd /, который содержит символические ссылки для открытия файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...