我有一个可能有文件描述符泄漏的进程的核心转储文件(它打开文件和套接字,但显然有时忘记关闭其中的一些)。有没有办法找到崩溃之前该进程已打开哪些文件和套接字?我不能轻易地重现崩溃,因此分析核心文件似乎是获得有关错误提示的唯一方法。Linux上的核心转储文件:如何获取已打开文件的信息?
回答
核心转储是进程在崩溃时可以访问的内存的副本。根据泄漏发生的方式,它可能已经失去了对手柄的引用,所以它可能被证明是无用的。
lsof列出系统中所有当前打开的文件,您可以检查其输出以查找泄露的套接字或文件。是的,你需要让流程运行。您可以使用特定的用户名来运行它,以便轻松辨别哪些是您正在调试的进程中的打开文件。
我希望别人有更好的信息:-)
您可以尝试使用strace
看到open
,socket
和close
调用程序发出。
编辑:我不认为你可以从核心获得信息;最多它将有文件描述符在某处,但这仍然不会给你实际的文件/套接字。 (假设您可以区分开放和封闭的文件描述符,我也怀疑这一点)。
查找/ proc/PID/fd /的另一种方法是查找某个进程已打开的文件 - 仅在运行时 - 其中包含用于打开文件的符号链接。
如果程序忘记关闭这些可能是因为像下面发生的资源:
fd = open("/tmp/foo",O_CREAT);
//do stuff
fd = open("/tmp/bar",O_CREAT); //Oops, forgot to close(fd)
现在我不会有在内存FOO的文件描述符。
如果没有发生这种情况,您可能能够找到文件描述符编号,但是再次,这不是很有用,因为它们不断变化,到调试时您将不知道哪个它当时的文件意味着它。
我真的认为你应该用strace,lsof和朋友来现场调试。
如果有一种方法可以从核心转储做到这一点,我急切地想知道它太:-)
最好的办法是安装于任何信号崩溃程序(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
然后你可以从你的信号处理程序返回后,你应该得到一个核心转储如常。
如果你有一个核心文件,而您与调试运行选项(-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)。
利用这些信息,您可以轻松找到导致崩溃的原因,打开哪些文件以及是否连接崩溃和文件描述符泄漏。
这并没有真正回答这个问题,即使用核心文件来发现打开的文件,而不是将调试输出添加到现有程序。无论如何,奥利弗都无法重现这个问题。 – craig65535 2016-11-03 17:22:49
我跳转到这些信息的方法之一就是在核心文件上运行strings
。例如,当我最近在核心上运行文件时,由于文件夹的长度,我会得到一个截断的参数列表。我知道我跑会从我的主目录打开的文件,所以我只是跑:
strings core.14930|grep jodie
但是,这是我有一个针和干草堆的情况。
我的错误诊断和分析过程中最近,我的客户提供我哪些得到了他的文件系统中生成一个核心转储,他为了迅速通过文件扫描并阅读其内容,我用命令去出站
字符串core.67545> coredump.txt 和更高版本我能够在文件编辑器中打开该文件。
- 1. 如何从核心文件获取有关崩溃的信息?
- 2. GDB +核心文件转储
- 3. 如何获取该文件仍然对ftp打开的信息
- 4. 如何在Linux中生成核心转储文件?
- 5. 如何让linux核心转储文件每次都被覆盖?
- 6. 从截断的嵌入式linux(arm)核心转储中获取断言信息
- 7. 如何使用Mono在Linux上获取文件信息
- 8. Apache的核心转储文件
- 9. 获取核心文件
- 10. 如何打开文件/目录获取信息窗口?
- 11. 如何在使用GDB生成核心转储文件时限制核心转储文件的大小
- 12. 如何从ETL文件获取文件转换信息
- 13. 获取已删除文件/文件夹的svn信息
- 14. 如何获取Linux中当前目录下的文件信息
- 15. 核心转储文件存储在iPhone上的位置?
- 16. GDB中的goroutine展开为golang exe文件的核心转储
- 17. 获取内容从文本文件转储信息到属性
- 18. 如何用已打开的可执行文件打开文件?
- 19. 如何打开和提取VBA中多个文件的信息
- 20. 打开OPENFILENAME对话框时获取媒体文件的信息
- 21. 获取打开文件的所有诊断信息
- 22. 核心转储文件格式
- 23. php核心转储文件位置
- 24. 核心转储文件名截断
- 25. 核心转储文件不产生
- 26. 写入文件时核心转储?
- 27. 核心转储信息没有在STDERR
- 28. 分析在linux上运行wireshark时创建的核心转储文件
- 29. 在linux内核中与进程核心转储创建相关的文件
- 30. 如何禁用核心转储文件的创建在WebSphere
真的!我忘记了这一点。 – 2008-09-12 09:55:33