大话Linux调试崩溃(理解记忆版)

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

通俗比喻
像用“代码显微镜”一行行看程序怎么跑的,哪里开始“抽风”。


终极调试口诀

  1. 一存:崩溃后先存核心文件和日志。

  2. 二看:用 gdb + bt 看调用栈。

  3. 三查:查日志和代码上下文。

  4. 四复现:尽量稳定复现问题。

  5. 五调试:用 GDB 断点/单步定位问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值