Подтвердить что ты не робот

Core dump files на Linux: как получить информацию об открытых файлах?

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

4b9b3361

Ответ 1

Если у вас есть файл ядра и вы скомпилировали программу с параметрами отладки (-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).

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

Ответ 2

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

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

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

Ответ 4

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

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

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

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

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

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

Ответ 5

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

strings core.14930|grep jodie

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

Ответ 6

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

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

Ответ 7

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

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

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

Ответ 8

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