Linux: 通过/proc/pid/stack查看程序卡在内核的什么地方

Linux: 通过/proc/pid/stack查看程序卡在内核的什么地方

机缘巧合吧,用到了这个知识点,记录一下!

1. 谁引入这个漂亮的功能?

patch讨论邮件列表

patch来自Ken Chen,大佬们来回拉扯,最终Ingo赞叹这是个beautiful patch!

[patch] add /proc/pid/stack to dump task's stack trace

哪个commit引入?

哪个版本包含?v2.6.28

git describe 默认会找到距离指定提交最近的标签,并且如果该标签不是直接指向该提交,则会提供额外的信息(如提交数量和哈希)。要获取最近的标签而不包括额外信息,可以使用 --tags 和 --abbrev=0 选项。

bash 复制代码
# git describe --tags --abbrev=0 2ec220e27f5040aec1e88901c1b6ea3d135787ad
v2.6.28

2. 用户线程和内核线程实例

分别以用户线程rsyslogd和内核线程kthreadd为例:

bash 复制代码
[root@CentOS8 ~]# ps -elf | grep -e rsyslogd -e kthreadd
1 S root           2       0  0  80   0 -     0 -      Dec02 ?        00:00:02 [kthreadd]
4 S root        1242       1  0  80   0 - 56463 -      Dec02 ?        00:01:18 /usr/sbin/rsyslogd -n

kthreadd, pid为2

bash 复制代码
[root@CentOS8 ~]# cat /proc/2/stack
[<0>] kthreadd+0x2e8/0x300
[<0>] ret_from_fork+0x1f/0x40

rsyslogd,pid为1242

bash 复制代码
[root@CentOS8 ~]# cat /proc/1242/stack
[<0>] poll_schedule_timeout.constprop.14+0x42/0x70
[<0>] do_select+0x6cb/0x770
[<0>] core_sys_select+0x20e/0x2f0
[<0>] kern_select+0xb5/0x110
[<0>] __x64_sys_select+0x20/0x30
[<0>] do_syscall_64+0x5b/0x1a0
[<0>] entry_SYSCALL_64_after_hwframe+0x65/0xca

3. /proc/pid/stack和其它debug方法的对比

/proc/pid/stack

  • 只反映当前时刻的stack,不同的时间读取的结果可能不一样
  • 显示内核栈,所以对于处于D状态的进程非常有用!

gdb

  • 只能查看进程用户栈
  • 可以打印变量
  • 可以把程序停住!

先用gdb的断点把程序停住,再看/proc/pid/stack,是不是有实用价值的debug方式?

perf

perf 是 Linux 性能分析工具的一部分,它可以用来收集性能数据,包括用户态和内核态的堆栈跟踪。例如:

bash 复制代码
perf record -g -p <pid> sleep 10
perf report

这将在 10 秒内记录进程的性能事件,之后你可以使用 perf report 来查看收集到的数据,包括堆栈跟踪。

/proc/<pid>/wchan

/proc/<pid>/wchan文件是 Linux 内核提供的一个接口,用于显示进程当前正在等待的内核函数或事件。当一个进程处于睡眠状态(即它正在等待某个事件发生,如 I/O 操作完成或信号量可用),wchan 文件会显示该进程在内核中等待的具体函数名称。

4 内核最新代码实现(kernel 6.13-rc2)

ARM/ARM64/Loongarch/x86等架构

CONFIG_STACKTRACE=y

CONFIG_ARCH_STACKWALK=y

cat /proc/pid/stack触发:

-> proc_pid_stack

-> stack_trace_save_regs

-> arch_stack_walk

-> kunwind_stack_walk

mips/arc等架构

CONFIG_STACKTRACE=y

CONFIG_ARCH_STACKWALK=n

​cat /proc/pid/stack触发:

-> proc_pid_stack

-> stack_trace_save_regs

-> save_stack_trace_tsk

欢迎收藏、点赞、关注、留言!

相关推荐
东软吴彦祖11 分钟前
包安装利用 LNMP 实现 phpMyAdmin 的负载均衡并利用Redis实现会话保持nginx
linux·redis·mysql·nginx·缓存·负载均衡
卷卷的小趴菜学编程33 分钟前
c++之List容器的模拟实现
服务器·c语言·开发语言·数据结构·c++·算法·list
艾杰Hydra36 分钟前
LInux配置PXE 服务器
linux·运维·服务器
多恩Stone39 分钟前
【ubuntu 连接显示器无法显示】可以通过 ssh 连接 ubuntu 服务器正常使用,但服务器连接显示器没有输出
服务器·ubuntu·计算机外设
慵懒的猫mi1 小时前
deepin分享-Linux & Windows 双系统时间不一致解决方案
linux·运维·windows·mysql·deepin
Allen Bright1 小时前
使用 JMeter 的 Autostop Listener 插件:自动化性能测试的守护者
运维·jmeter·自动化
晚秋贰拾伍1 小时前
设计模式的艺术-代理模式
运维·安全·设计模式·系统安全·代理模式·运维开发·开闭原则
阿无@_@1 小时前
2、ceph的安装——方式二ceph-deploy
linux·ceph·centos
牙牙7051 小时前
ansible一键安装nginx二进制版本
服务器·nginx·ansible
hhzz1 小时前
ansible自动化运维实战--复制模块和用户模块(3)
运维·自动化·ansible