排查问题的知识记录

1. 写在最前面

最近这几周在忙着上线服务,不是在修 bug ,就是在查 bug 的路上。不过这也让笔者陷入反思,按照插件的方式引入其他人提供的服务,真的利大于弊吗?

对这个问题的答案,个人观点是,如果每个插件都是按照标准流程且经过严格的测试,那这种方式确实可以带来一定的好处;但是如果在项目工期交付紧急的情况下,可能各个插件的提供方并未经过严格的测试,这样所有的测试压力就完全给到业务侧。坏处是业务侧要不停地分析非业务的 crash 。

注:一个下午分析 3 个 crash,还基本都跟业务逻辑无关,笔者真的觉得这个时间可以花费处理业务更痛的问题上。

但是好在分析各种 crash 的问题上,也学到了很多新知识,那就顺便记录一下最近学习的新知识们吧!

2. C++ 程序 crash 产生 core dump 文件命名

核心转储文件(core dump)是操作系统在程序崩溃时生成的文件,它包含了程序崩溃时的内存状态。核心转储文件的命名模式可以通过 core_pattern 配置进行设置。你提到的 core-%e-%t-%p-%u-%h 是一个示例命名模式,下面是对每个部分的解释:

  • %e :表示程序的可执行文件名(不带路径和扩展名)。例如,如果可执行文件是 my_program,那么 %e 将被替换为 my_program
  • %t:表示崩溃时的时间戳。这个时间戳通常是自 Unix 纪元(1970年1月1日)以来的秒数,表示程序崩溃的时间。
  • %p :表示崩溃时的进程 ID(PID)。每个运行中的进程都有一个唯一的进程 ID,使用 %p 可以在文件名中包含这个信息。
  • %u:表示崩溃时的用户 ID(UID)。这个值表示运行程序的用户的唯一标识符。
  • %h:表示崩溃时的主机名。这个值是运行程序的计算机的主机名,可以帮助识别崩溃发生的环境。

2.1 示例

假设你的程序名为 my_program,在2025 年 3 月 7 日 12:34:56崩溃,崩溃时的进程 ID 为 1234,用户 ID 为 1000,主机名为 myhost,那么生成的核心转储文件名可能是:

复制代码
core-my_program-1615118896-1234-1000-myhost

这种命名模式可以帮助开发人员更容易地识别和管理不同的核心转储文件,特别是在调试多个崩溃或在不同环境中运行的情况下。

3. 分析进程调用链

对于多线程的情况下,进程有可能因为某个线程卡住,导致整个进程卡主。是时候使用 pstree、pstack、strace 三兄弟进行分析。

好的,下面是 pstreepstackstrace 命令的详细说明,包括它们的功能、用法以及具体的使用示例。

3.1 pstree

3.1.1 命令说明

pstree 是一个用于显示进程树的命令,它以树状结构展示进程及其父子关系。通过这个命令,用户可以直观地看到哪些进程是由其他进程启动的。

3.1.2 常用选项
  • -p:显示进程 ID。
  • -u:显示进程的用户。
  • -a:显示进程的命令行参数。
  • -n:按进程名称排序。
3.1.3 使用示例
  1. 查看当前进程树

    复制代码
    pstree

    输出示例:

    markdown 复制代码
    systemd─┬─gnome-session─┬─gnome-shell─┬─Xorg
            │                │              └─gnome-terminal─└─bash
            │                └─nautilus
            └─sshd───sshd───bash
  2. 显示进程 ID

    css 复制代码
    pstree -p

    输出示例:

    scss 复制代码
    systemd(1)─┬─gnome-session(1234)─┬─gnome-shell(2345)─┬─Xorg(3456)
               │                     │                     └─gnome-terminal(4567)─└─bash(5678)
               │                     └─nautilus(6789)
               └─sshd(7890)───sshd(8901)───bash(9012)

3.2 pstack

3.2.1 命令说明

pstack 用于查看指定进程的堆栈跟踪信息。它可以帮助开发者分析程序在某一时刻的调用状态,特别是在调试程序时非常有用。

3.2.2 使用示例
  1. 查看进程的堆栈信息: 假设您有一个正在运行的进程,其进程 ID 为 1234。

    yaml 复制代码
    pstack 1234

    输出示例:

    css 复制代码
    #0  0x00007f8d3c123456 in some_function () from /path/to/library.so
    #1  0x00007f8d3c123789 in another_function () from /path/to/library.so
    #2  0x00007f8d3c123abc in main () from /path/to/executable

3.3 strace

3.3.1 命令说明

strace 是一个用于跟踪程序的系统调用和信号的命令。它能够记录程序与内核的交互,包括文件操作、网络请求等,适合用于调试和性能分析。

3.3.2 常用选项
  • -p <pid>:跟踪指定进程的系统调用。
  • -o <file>:将输出写入指定文件。
  • -e <expression>:只跟踪特定的系统调用。
3.3.3 使用示例
  1. 跟踪新程序的系统调用 : 假设您要跟踪一个名为 my_program 的程序。

    bash 复制代码
    strace ./my_program

    输出示例:

    scss 复制代码
    open("file.txt", O_RDONLY)          = 3
    read(3, "Hello, World!\n", 1024)    = 13
    write(1, "Hello, World!\n", 13)      = 13
    close(3)                             = 0
  2. 跟踪已运行的进程: 如果您想跟踪一个已经在运行的进程,假设其进程 ID 为 5678。

    css 复制代码
    strace -p 5678

3.4 总结

  • pstree:用于查看进程的层级关系,帮助用户理解进程之间的父子关系。
  • pstack:用于查看进程的堆栈信息,适合调试程序的调用路径。
  • strace:用于跟踪程序的系统调用,深入分析程序与操作系统的交互。

4. 碎碎念

忙是忙了点,但是好在还是又在积累成长吖

  • 少年的肩膀,就该这样才对嘛,什么家国仇恨,浩然正气的,都不要急,先挑起清风明月、杨柳依依和草长莺飞,少年郎的肩头,本就应当满是美好的事物啊。
  • 努力想得到什么东西,其实只要沉着镇静、实事求是,就可以轻易地、神不知鬼不觉地达到目的。
    而如果过于使劲,闹得太凶,太幼稚,太没有经验,就哭啊,抓啊,拉啊,像一个小孩扯桌布,结果却是一无所获,只不过把桌上的好东西都扯到地上,永远也得不到了。

5.参考资料

相关推荐
撸猫79110 分钟前
HttpSession 的运行原理
前端·后端·cookie·httpsession
嘵奇40 分钟前
Spring Boot中HTTP连接池的配置与优化实践
spring boot·后端·http
子燕若水1 小时前
Flask 调试的时候进入main函数两次
后端·python·flask
程序员爱钓鱼1 小时前
跳转语句:break、continue、goto -《Go语言实战指南》
开发语言·后端·golang·go1.19
Persistence___2 小时前
SpringBoot中的拦截器
java·spring boot·后端
嘵奇2 小时前
Spring Boot 跨域问题全解:原理、解决方案与最佳实践
java·spring boot·后端
景天科技苑4 小时前
【Rust泛型】Rust泛型使用详解与应用场景
开发语言·后端·rust·泛型·rust泛型
lgily-12256 小时前
常用的设计模式详解
java·后端·python·设计模式
意倾城7 小时前
Spring Boot 配置文件敏感信息加密:Jasypt 实战
java·spring boot·后端
火皇4057 小时前
Spring Boot 使用 OSHI 实现系统运行状态监控接口
java·spring boot·后端