1. 收集崩溃信息:先“保存现场”
目标:程序崩溃时,立刻保存关键证据(拍照记录车祸现场)。
关键操作:
-
确保生成核心转储文件(Core Dump)
-
核心转储文件是程序崩溃时的“内存快照”,记录崩溃瞬间的状态。
-
执行以下命令确保系统允许生成:
ulimit -c unlimited # 解除核心文件大小限制 echo "/tmp/core.%e.%p" > /proc/sys/kernel/core_pattern # 指定保存路径
-
ulimit 是一个 shell 内建命令,用于控制当前 shell 会话的资源限制。其中,-c 选项表示“core dump 文件的最大大小”。默认情况下,Linux 系统会限制生成的核心文件的大小。通过设置 ulimit -c unlimited,你可以解除这个限制,允许系统生成任意大小的核心文件。
-c:指定的是 core dump 文件的大小限制。
unlimited:表示没有限制,也就是说,核心文件的大小将不再受到限制。
这条命令设置了核心文件保存的路径和命名格式。/proc/sys/kernel/core_pattern 是一个系统文件,控制内核生成核心文件时的命名和存放位置。
-
echo:向/proc/sys/kernel/core_pattern文件写入新的内容。 -
"/tmp/core.%e.%p":这是设置的核心文件的命名模板:-
%e:程序的名称(执行文件名)。 -
%p:进程的 PID(进程 ID)。
-
通过这个命令,核心文件会被保存到 /tmp 目录,并且文件名格式为 core.程序名.进程ID。
示例:
假设一个程序 test 崩溃并生成核心文件,如果进程 ID 是 1234,那么核心文件的名称将会是 /tmp/core.test.1234。
崩溃后会在 /tmp 下生成类似 core.program.1234 的文件。
-
收集系统日志
-
查看系统日志,寻找崩溃前后的线索:
dmesg | tail -20 # 查看内核日志(如段错误信息) journalctl -xe # 查看系统服务日志(需 systemd) cat /var/log/syslog # 通用系统日志
-
程序突然挂了,你要先保存它的“尸体”(核心文件)和“临终遗言”(日志),而不是直接重启!
1. dmesg | tail -20
dmesg 是一个用于显示内核环缓冲区的命令,它会输出系统启动时的日志信息,包括硬件检测、驱动程序加载、内核错误、设备连接等信息。这些信息对于诊断与硬件相关的问题非常有用,尤其是段错误、内存问题等。
-
dmesg:显示内核缓冲区中的日志信息。 -
|:管道符号,将dmesg命令的输出传递给tail命令。 -
tail -20:输出dmesg命令的最后 20 行日志。这通常用于查看最近的日志信息,尤其是系统崩溃或段错误(segfault)发生后的相关日志。
示例:
如果系统崩溃或者出现段错误,你可以使用这条命令来查看内核输出的相关错误信息,如进程崩溃、硬件错误或内存问题。
2. journalctl -xe
journalctl 是用来查询系统日志的命令,它与 systemd 系统的日志管理器配合使用,可以查询所有的系统日志,包括应用程序日志、内核日志、用户日志等。
-
journalctl:查看由systemd管理的日志。 -
-xe:两个选项:-
-x:显示详细的错误消息,特别是与日志相关的诊断信息。 -
-e:显示日志的最后部分(类似tail命令),即最新的日志信息。
-
示例:
当你希望查看系统服务(如启动失败、崩溃、挂起的服务等)相关的详细日志时,这条命令非常有用,尤其是在系统或应用崩溃的情况下。它提供了更为详细的日志信息,可以帮助你找出服务出错的原因。
3. cat /var/log/syslog
syslog 是一个通用的系统日志文件,包含了大部分与系统操作相关的消息,包括内核消息、服务消息和应用程序错误等。这个文件常常用来查看系统的整体状态,特别是在无法确定问题来源时。
-
cat:用于显示文件内容的命令。 -
/var/log/syslog:系统日志文件,通常包含较为全面的系统信息和错误消息。包括网络配置、系统服务、定时任务等的信息。
示例:
如果你想查看系统发生的事件或错误,而不仅仅是内核错误,/var/log/syslog 是一个很好的选择。它记录了大量的系统信息,通常会包括服务启动、关闭、系统更新、警告和错误等信息。
总结:
-
dmesg | tail -20:查看最近的内核日志,特别是与硬件和内核级别错误(如段错误)相关的消息。 -
journalctl -xe:查看由systemd管理的系统日志,尤其是服务相关的错误信息。 -
cat /var/log/syslog:查看系统的通用日志文件,记录了较为全面的系统和应用程序日志信息。
2. 分析核心转储文件:用“法医工具”验尸
目标:用 GDB(调试器)解剖核心文件,找到崩溃位置。
关键操作:
gdb /path/to/your/program /tmp/core.program.1234 # 加载程序和核心文件
-
GDB 内常用命令:
bt(backtrace) # 查看崩溃时的函数调用栈(最重要!) info registers # 查看寄存器状态 print 变量名 # 打印崩溃时的变量值 list # 查看崩溃附近的代码
通俗解释:
-
bt会显示崩溃时程序执行到哪一行代码,像“调用栈录像回放”。 -
如果看到
Segmentation fault (core dumped),大概率是访问了非法内存(如空指针)。
3. 检查系统日志:找“目击证人”
目标:从日志中找崩溃的间接线索(如资源不足、权限问题)。
重点查看:
-
崩溃时间点:确认日志时间戳和崩溃时间是否匹配。
-
错误关键词:如
OOM(内存不足)、segfault(段错误)、permission denied。
示例:
grep -i "segfault" /var/log/syslog # 搜索段错误记录
通俗比喻:
就像破案时查监控录像,看崩溃前有没有人(其他进程)干了可疑的事。
4. 重现崩溃:让“凶手”再次作案
目标:如果能稳定复现崩溃,调试会更容易。
方法:
-
记录崩溃时的操作步骤:如输入什么数据、点击哪个按钮。
-
简化复现条件:去掉无关操作,用最小化场景复现(如特定输入文件)。
通俗建议:
如果崩溃是“偶尔发生”,可以尝试:
-
写一个自动化脚本反复测试(比如循环运行程序)。
-
用
stress工具模拟高负载环境。
5. 使用调试器(GDB):实时“蹲点抓凶”
目标:直接调试运行中的程序,观察崩溃瞬间。
两种方式:
-
调试已崩溃的程序(用核心文件,见第2步)。
-
实时附加到运行中的进程:
gdb -p <PID> # 附加到正在运行的进程-
然后设置断点(
break 行号)、单步执行(next/step)。
-
通俗技巧:
-
如果崩溃前有警告,可以用
break在可疑函数处设断点。 -
用
watch 变量名监控变量何时被修改。
6. 跟踪代码执行流:逐帧“慢动作回放”
目标:一步步执行代码,观察变量和逻辑是否正常。
关键操作:
-
单步调试:
next(n) # 执行下一行(不进入函数) step(s) # 执行下一行(进入函数内部) continue(c) # 继续运行直到下一个断点 -
检查变量:
print x # 查看变量 x 的值 display x # 每次暂停时自动打印 x
通俗比喻:
像用“代码显微镜”一行行看程序怎么跑的,哪里开始“抽风”。
终极调试口诀
-
一存:崩溃后先存核心文件和日志。
-
二看:用
gdb + bt看调用栈。 -
三查:查日志和代码上下文。
-
四复现:尽量稳定复现问题。
-
五调试:用 GDB 断点/单步定位问题。

1928

被折叠的 条评论
为什么被折叠?



