如何从 /var/crash 读取崩溃文件

如何从 /var/crash 读取崩溃文件

php-fpm 崩溃了,并转储了一个文件

/var/crash/_usr_sbin_php5-fpm.1002.crash

该文件中有一些信息,但我要找的是名为 CoreDump 的部分,采用 base64 编码格式。我如何才能读取崩溃时正在运行的内容?

答案1

如果您不想为工具安装一堆子依赖项,您可以将 apport 格式解压为单独的文件,然后像往常一样apport-retrace仅使用CoreDumpdump 。gdb

  1. apport-unpack systemGeneratedCrashReportPath.crash yourNewUnpackDirectoryHere

  2. cd yourNewUnpackDirectoryHere/

  3. gdb `cat ExecutablePath` CoreDump (请注意这里的反引号!)

  4. bt(输出实际回溯)

    注意:apport-unpack在解压操作时有时会崩溃(apport 似乎完全坏了...xD),但你的 CoreDump 和其他文件会在那里,只需忽略它并在/var/crash你将它们移动到其他地方后删除所有 .crash 文件,以允许系统从那里的相同应用程序输出新的崩溃报告。

答案2

有一个名为 的工具apport-retrace可以读取 .crash 文件,并允许您使用全符号堆栈跟踪填充它,或者gdb使用核心转储运行会话。要启动 gdb 会话,请运行apport-retrace -g CRASHFILE.crash。请注意,您需要安装 -dbg 软件包才能获得良好的堆栈跟踪。

话虽如此(我不是 PHP 专家),实际上可能是你在某个文件中写入的内容导致了崩溃。

答案3

如何在 GDB 上获取源代码

在 Ubuntu 23.10 上进行测试后,我设法让 GDB 与 stamster 的答案一起工作:https://askubuntu.com/a/947532/52975但是没有显示软件包的源代码。由于我最近遇到了一次崩溃,我想调试一下,因此我将借此机会记录如何进行调试。

首先进行设置,以便您能够使用源 hello world 进行包调试,并gdb ls按照以下说明使用源进行正确调试:如何为已安装的软件包安装调试符号?

接下来,完成之后:

gdb `cat ExecutablePath` CoreDump

这是我所看到的:

>>> bt
#0  __pthread_kill_implementation (no_tid=0, signo=5, threadid=<optimized out>) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=5, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=5) at ./nptl/pthread_kill.c:89
#3  0x00007f62b5842866 in __GI_raise (sig=5) at ../sysdeps/posix/raise.c:26
#4  0x0000562470b03bda in ??? ()
#5  0x00007f62b5842910 in <signal handler called> () at /lib/x86_64-linux-gnu/libc.so.6
#6  0x00007f62b62e5867 in g_log_structured_array () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#7  0x00007f62b62e5b52 in g_log_default_handler () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#8  0x00007f62b62e69e2 in g_logv () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#9  0x00007f62b62e6ca3 in g_log () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#10 0x00007f62b68ab59e in ??? () at /usr/lib/x86_64-linux-gnu/mutter-13/libmutter-mtk-13.so.0
#11 0x00007f62b5704a5b in _XError () at /lib/x86_64-linux-gnu/libX11.so.6
#12 0x00007f62b1f63adb in ??? () at /lib/x86_64-linux-gnu/libGLX.so.0
#13 0x00007f62b5f0962f in ??? () at /usr/lib/x86_64-linux-gnu/mutter-13/libmutter-cogl-13.so.0

但没有框架有源。

从函数名称来看,第一个可能有趣的框架是,#10 0x00007f62b68ab59e in ??? () at /usr/lib/x86_64-linux-gnu/mutter-13/libmutter-mtk-13.so.0所以让我们尝试获取它的源代码。

首先我识别一下包裹:

apt-file search /usr/lib/x86_64-linux-gnu/mutter-13/libmutter-mtk-13.so.0

这使:

libmutter-13-0: /usr/lib/x86_64-linux-gnu/mutter-13/libmutter-mtk-13.so.0
libmutter-13-0: /usr/lib/x86_64-linux-gnu/mutter-13/libmutter-mtk-13.so.0.0.0

因此我们得到调试符号和源代码:

sudo apt install libmutter-13-0-dbgsym

但 TODO 却失败了:

The following packages have unmet dependencies:
 libmutter-13-0-dbgsym : Depends: libmutter-13-0 (= 45.2-0ubuntu3) but 45.2-0ubuntu2~really45.0 is to be installed
E: Unable to correct problems, you have held broken packages.

编辑:稍后我再次尝试时,它又恢复了。想想吧。

好的,让我们尝试另一个有趣的框架#11 0x00007f62b5704a5b in _XError () at /lib/x86_64-linux-gnu/libX11.so.6

apt-file search /lib/x86_64-linux-gnu/libX11.so.6

这使:

libx11-6: /usr/lib/x86_64-linux-gnu/libX11.so.6
libx11-6: /usr/lib/x86_64-linux-gnu/libX11.so.6.4.0

因此我们得到以下调试符号:

sudo apt install libx11-6-dbgsym

以及以下来源:

cd /usr/src
sudo apt source libx11-6

然后在GDB上:

frame 11

显示:

#11 0x00007f62b5704a5b in _XError (dpy=0x562471d040d0, rep=<optimized out>) at ../../src/XlibInt.c:1503
1503    ../../src/XlibInt.c: No such file or directory.

所以我们这样做:

set substitute-path ../.. /usr/src/libx11-1.8.6

进而:

list

提供来源:

1498            dpy->error_threads = &thread_info;
1499            if (dpy->lock)
1500                (*dpy->lock->user_lock_display)(dpy);
1501            UnlockDisplay(dpy);
1502    #endif
1503            rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
1504    #ifdef XTHREADS
1505            LockDisplay(dpy);
1506            if (dpy->lock)
1507                (*dpy->lock->user_unlock_display)(dpy);

好的,让我们尝试另一个#12 0x00007f62b1f63adb in ??? () at /lib/x86_64-linux-gnu/libGLX.so.0

apt-file search /lib/x86_64-linux-gnu/libGLX.so.0

给出:

libglx0: /usr/lib/x86_64-linux-gnu/libGLX.so.0
libglx0: /usr/lib/x86_64-linux-gnu/libGLX.so.0.0.0

所以:

sudo apt install libglx0-dbgsym
cd /usr/src
sudo apt source libglx0

然后在GDB中:

frame 12

给出:

#12 0x00007f62b1f63adb in __glXSendError (dpy=0x562471d040d0, errorCode=<optimized out>, resourceID=0, minorCode=<optimized out>, coreX11error=0) at ../src/GLX/libglx.c:805
805     ../src/GLX/libglx.c: No such file or directory.

所以:

set substitute-path .. /usr/src/libglvnd-1.6.0

现在list给出:

>>> list
800         error.majorCode = dpyInfo->glxMajorOpcode;
801         if (!coreX11error) {
802             error.errorCode += dpyInfo->glxFirstError;
803         }
804
805         _XError(dpy, &error);
806
807         UnlockDisplay(dpy);
808     }
809

_XError好的,它对两个包都起作用了,我们清楚地看到之前调用的库!

这让我很疑惑:如何substitute-path为每个TODO使用不同的单独库?因为会有冲突。

有关的:

相关内容