php-fpm 崩溃了,并转储了一个文件
/var/crash/_usr_sbin_php5-fpm.1002.crash
该文件中有一些信息,但我要找的是名为 CoreDump 的部分,采用 base64 编码格式。我如何才能读取崩溃时正在运行的内容?
答案1
如果您不想为工具安装一堆子依赖项,您可以将 apport 格式解压为单独的文件,然后像往常一样apport-retrace
仅使用CoreDump
dump 。gdb
apport-unpack systemGeneratedCrashReportPath.crash yourNewUnpackDirectoryHere
cd yourNewUnpackDirectoryHere/
gdb `cat ExecutablePath` CoreDump
(请注意这里的反引号!)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使用不同的单独库?因为会有冲突。
有关的: