2008-09-12 22 views
26

我有一个可能有文件描述符泄漏的进程的核心转储文件(它打开文件和套接字,但显然有时忘记关闭其中的一些)。有没有办法找到崩溃之前该进程已打开哪些文件和套接字?我不能轻易地重现崩溃,因此分析核心文件似乎是获得有关错误提示的唯一方法。Linux上的核心转储文件:如何获取已打开文件的信息?

回答

1

核心转储是进程在崩溃时可以访问的内存的副本。根据泄漏发生的方式,它可能已经失去了对手柄的引用,所以它可能被证明是无用的。

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

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

3

您可以尝试使用strace看到opensocketclose调用程序发出。

编辑:我不认为你可以从核心获得信息;最多它将有文件描述符在某处,但这仍然不会给你实际的文件/套接字。 (假设您可以区分开放和封闭的文件描述符,我也怀疑这一点)。

+0

真的!我忘记了这一点。 – 2008-09-12 09:55:33

0

查找/ proc/PID/fd /的另一种方法是查找某个进程已打开的文件 - 仅在运行时 - 其中包含用于打开文件的符号链接。

2

如果程序忘记关闭这些可能是因为像下面发生的资源:

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

现在我不会有在内存FOO的文件描述符。

如果没有发生这种情况,您可能能够找到文件描述符编号,但是再次,这不是很有用,因为它们不断变化,到调试时您将不知道哪个它当时的文件意味着它。

我真的认为你应该用strace,lsof和朋友来现场调试。

如果有一种方法可以从核心转储做到这一点,我急切地想知道它太:-)

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 

然后你可以从你的信号处理程序返回后,你应该得到一个核心转储如常。

11

如果你有一个核心文件,而您与调试运行选项(-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)。

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

+0

这并没有真正回答这个问题,即使用核心文件来发现打开的文件,而不是将调试输出添加到现有程序。无论如何,奥利弗都无法重现这个问题。 – craig65535 2016-11-03 17:22:49

2

我跳转到这些信息的方法之一就是在核心文件上运行strings。例如,当我最近在核心上运行文件时,由于文件夹的长度,我会得到一个截断的参数列表。我知道我跑会从我的主目录打开的文件,所以我只是跑:

strings core.14930|grep jodie 

但是,这是我有一个针和干草堆的情况。

我的错误诊断和分析过程中
2

最近,我的客户提供我哪些得到了他的文件系统中生成一个核心转储,他为了迅速通过文件扫描并阅读其内容,我用命令去出站

字符串core.67545> coredump.txt 和更高版本我能够在文件编辑器中打开该文件。

相关问题