我有一个进程的核心转储文件可能有文件描述符泄漏(它打开文件和套接字,但显然有时会忘记关闭其中一些).有没有办法在崩溃之前找出进程打开了哪些文件和套接字?我无法轻易重现崩溃,因此分析核心文件似乎是获取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).
有了这些信息,您可以轻松找到导致崩溃的原因,打开哪些文件以及是否连接了崩溃和文件描述符泄漏.
最好的办法是为任何崩溃程序的信号(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)
然后你可以从信号处理程序返回,你应该像往常一样获得核心转储.
核心转储是进程崩溃时可以访问的内存的副本。根据泄漏发生的方式,它可能会丢失对句柄的引用,因此它可能被证明是无用的。
lsof 列出了系统中所有当前打开的文件,您可以检查其输出以查找泄漏的套接字或文件。是的,您需要运行该进程。您可以使用特定的用户名运行它,以便轻松辨别正在调试的进程中打开的文件。
我希望其他人有更好的信息:-)
| 归档时间: |
|
| 查看次数: |
31231 次 |
| 最近记录: |