Linux上的核心转储文件:如何获取打开文件的信息?

oli*_*ver 30 linux crash

我有一个进程的核心转储文件可能有文件描述符泄漏(它打开文件和套接字,但显然有时会忘记关闭其中一些).有没有办法在崩溃之前找出进程打开了哪些文件和套接字?我无法轻易重现崩溃,因此分析核心文件似乎是获取bug的唯一方法.

ter*_*nus 10

如果您有一个核心文件,并且您已使用debuging选项(-g)编译该程序,则可以查看核心被转储的位置:

$ gcc -g -o something something.c
$ ./something
Segmentation fault (core dumped)
$ gdb something core
Run Code Online (Sandbox Code Playgroud)

你可以用它来做一些验尸后的调试.一些gdb命令:br打印堆栈,fr跳转到给定的堆栈帧(参见br的输出).

现在,如果你想查看在分段错误时打开哪些文件,只需处理SIGSEGV信号,在处理程序中,只需转储/ proc/PID/fd目录的内容(即使用system('ls -l/proc)/PID/fs')或execv).

有了这些信息,您可以轻松找到导致崩溃的原因,打开哪些文件以及是否连接了崩溃和文件描述符泄漏.

  • 这并不能真正回答这个问题,即使用核心文件发现打开的文件,而不是将调试输出添加到现有程序中。无论如何,奥利弗都无法重现问题。 (3认同)

Mar*_*hio 5

最好的办法是为任何崩溃程序的信号(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
Run Code Online (Sandbox Code Playgroud)

然后你可以从信号处理程序返回,你应该像往常一样获得核心转储.


Vin*_*vic 1

核心转储是进程崩溃时可以访问的内存的副本。根据泄漏发生的方式,它可能会丢失对句柄的引用,因此它可能被证明是无用的。

lsof 列出了系统中所有当前打开的文件,您可以检查其输出以查找泄漏的套接字或文件。是的,您需要运行该进程。您可以使用特定的用户名运行它,以便轻松辨别正在调试的进程中打开的文件。

我希望其他人有更好的信息:-)