我有一个可能存在文件描述符泄漏的进程的核心转储文件(它打开文件和套接字,但显然有时会忘记关闭其中一些)。有没有办法在崩溃之前找出进程打开了哪些文件和套接字?我不能轻易地重现崩溃,因此分析核心文件似乎是获取漏洞提示的唯一方法。
答案 0 :(得分:10)
如果您有一个核心文件,并且您已使用debuging选项(-g)编译该程序,则可以看到核心被转储的位置:
$ gcc -g -o something something.c
$ ./something
Segmentation fault (core dumped)
$ gdb something core
你可以用它来做一些验尸后的调试。一些gdb命令:br打印堆栈,fr跳转到给定的堆栈帧(参见br的输出)。
现在,如果您想查看在分段错误时打开哪些文件,只需处理SIGSEGV信号,并在处理程序中,只需转储/ proc / PID / fd目录的内容(即使用system('ls - ) l / proc / PID / fs')或execv)。
通过这些信息,您可以轻松找到导致崩溃的原因,打开哪些文件以及是否连接了崩溃和文件描述符泄漏。
答案 1 :(得分:4)
最好的办法是安装信号处理程序,以防止程序崩溃(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
然后你可以从你的信号处理程序返回,你应该像往常一样获得核心转储。
答案 2 :(得分:3)
您可以尝试使用strace
查看该计划发出的open
,socket
和close
来电。
编辑:我认为你无法从核心获取信息;最多它会在某处有文件描述符,但是这仍然没有给你实际的文件/套接字。 (假设您可以区分打开和关闭的文件描述符,我也怀疑。)
答案 3 :(得分:3)
我跳转到此信息的方法之一就是在核心文件上运行strings
。例如,当我最近在核心上运行文件时,由于文件夹的长度,我会得到一个截断的参数列表。我知道我的运行会从我的主目录中打开文件,所以我跑了:
strings core.14930|grep jodie
但这是我有针和大海捞针的情况。
答案 4 :(得分:2)
如果程序忘记关闭这些资源,可能是因为发生了以下情况:
fd = open("/tmp/foo",O_CREAT);
//do stuff
fd = open("/tmp/bar",O_CREAT); //Oops, forgot to close(fd)
现在我不会在内存中拥有foo的文件描述符。
如果没有发生这种情况,您可能会找到文件描述符编号,但是再次,这不是很有用,因为它们不断变化,当您进行调试时,您将不知道哪个文件它实际上意味着当时。
我真的认为你应该用strace,lsof和朋友调试这个。
如果有办法从核心转储中做到这一点,我也很想知道它: - )
答案 5 :(得分:2)
最近在我的错误故障排除和分析过程中,我的客户向我提供了一个在他的文件系统中生成的coredump,然后他离开了工作站,以便快速浏览文件并阅读其内容我使用了命令
strings core.67545> coredump.txt 后来我能够在文件编辑器中打开文件。
答案 6 :(得分:1)
核心转储是进程在崩溃时可以访问的内存的副本。根据泄漏的发生方式,它可能已经失去了对手柄的引用,因此它可能被证明是无用的。
lsof列出系统中当前打开的所有文件,您可以检查其输出以查找泄漏的套接字或文件。是的,您需要让流程运行。您可以使用特定的用户名运行它,以便轻松识别正在调试的进程中的打开文件。
我希望别人有更好的信息: - )
答案 7 :(得分:0)
查找进程已打开的文件的另一种方法 - 仅在运行时期间 - 查看/ proc / PID / fd /,其中包含用于打开文件的符号链接。