файлы дампа ядра в Linux: как получить информацию об открытых файлах?

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


person oliver    schedule 12.09.2008    source источник


Ответы (8)


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

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

Вы можете использовать это для отладки после вскрытия. Несколько команд gdb: bt печатает стек, fr переходит к заданному кадру стека (см. вывод bt).

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

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

person terminus    schedule 15.09.2008
comment
На самом деле это не отвечает на вопрос об использовании основного файла для обнаружения открытых файлов, а не о добавлении отладочного вывода в существующую программу. Оливер все равно не может воспроизвести проблему. - person craig65535; 03.11.2016

Лучше всего установить обработчик сигнала для любого сигнала, вызывающего сбой вашей программы (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

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

person Martin Del Vecchio    schedule 12.09.2008

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

strings core.14930|grep jodie

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

person JodieC    schedule 19.12.2014

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

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

person mweerden    schedule 12.09.2008

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

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

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

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

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

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

person Vinko Vrsalovic    schedule 12.09.2008

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

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

person Pinak Mazumdar    schedule 16.09.2015

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

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

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

person Vinko Vrsalovic    schedule 12.09.2008

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

person skolima    schedule 12.09.2008