【crash调试验证】获取task与cgroup

crash基本使用

  • 在crash中通过 [想要查看的参数] [参数地址] 可以看到当前的数据
    如 css_set 0xffff8f4871aad840
    或 css_set.cg_links 0xffff8f4871aad840
  • list -H [表头地址] 遍历链表
  • struct -o [数据地址] 查看指定数据的数据结构

crash> list help
NAME
list - linked list.
.
SYNOPSIS
list [[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]
[-r|-B] [-h|-H] start

crash获取进程的task

# 获取设备的task_struct
# 1. task [pid]
crash> task 1987
PID: 1987   TASK: ffff8f47fb3f4200  CPU: 1   COMMAND: "sleep"
struct task_struct {
  state = 1, 
 ... ...
     
# 2. 先获取地址,再task [address]
crash> ps | grep sleep
   1987   1862   1  ffff8f47fb3f4200  IN   0.0  108052    620  sleep
crash> task ffff8f47fb3f4200
PID: 1987   TASK: ffff8f47fb3f4200  CPU: 1   COMMAND: "sleep"
struct task_struct {
  state = 1, 
  stack = 0xffff8f47e9a28000, 
  ... ...

获取task对应的cgroup

linux中没有数据结构直接描述task所属的cgroup,而是通过css来包含了这层关系。因为实际运行时,获取task所属cgroup的操作请求出现频率比较小,而请求子系统状态的操作会非常频繁。参考文档

可以通过两条路径获取到

  1. task->css_set->css-> cgroup
# 创建一个测试进程
[root@aliyun-xxx ~]# sleep 36000 &
[1] 6997
    
[root@aliyun-xxx ~]# sleep 36000 &  # 默认cgroup,用于对比
[2] 2893
    
# task-> css_set
# 查看进程对应的css_set
crash> task -R cgroups 6997
PID: 6997   TASK: ffff8f47f5166300  CPU: 1   COMMAND: "sleep"
  cgroups = 0xffff8f47e5a20cc0, 


# task -> css_set -> css
# 对比默认cgroup的css,可以发现pids:/test对应的css地址为 0xffff8f47e9f93720
crash> css_set.subsys 0xffff8f47e5a20cc0
  subsys = {0xffffffff9c464520, 0xffffffff9c90abc0, 0xffffffff9c45d220, 0xffff8f487b14d400, 0xffff8f487b169a80, 0xffff8f487b13a8a0, 0xffff8f487b13a900, 0xffffffff9c4d6820, 0xffff8f487b13a960, 0xffff8f487b139d80, 0xffff8f47e9f93720, 0xffff8f487b10d300}

# 默认cgroup进程的css
crash> css_set.subsys 0xffff8f47aac45900
  subsys = {0xffffffff9c464520, 0xffffffff9c90abc0, 0xffffffff9c45d220, 0xffff8f487b14d400, 0xffff8f487b169a80, 0xffff8f487b13a8a0, 0xffff8f487b13a900, 0xffffffff9c4d6820, 0xffff8f487b13a960, 0xffff8f487b139d80, 0xffff8f487b13a9c0, 0xffff8f487b10d300}



# task -> css_set -> css -> cgroup
# 以pids为例,获取到task的cgroup pids:/test
crash> cgroup_subsys_state 0xffff8f47e9f93720
struct cgroup_subsys_state {
  cgroup = 0xffff8f4776836800,    # get !!
  refcnt = {
    counter = 1
  }, 
  flags = 2, 
  id = 0x0, 
  dput_work = {
    data = {
      counter = 68719476704
    }, 
    entry = {
      next = 0xffff8f47e9f93748, 
      prev = 0xffff8f47e9f93748
    }, 
    func = 0xffffffff9b928c70
  }
}
  1. task-> css_set-> cg_cgroup_link -> cgroup
# 创建一个测试进程
[root@aliyun-xxx ~]# sleep 36000 &
[1] 6997
    

# task-> css_set
# 查看进程对应的css_set
crash> task -R cgroups 6997
PID: 6997   TASK: ffff8f47f5166300  CPU: 1   COMMAND: "sleep"
  cgroups = 0xffff8f47e5a20cc0, 


# 查看task对应的css_set的cg_links(指向关联的cg_cgroup_link)
# task-> css_set-> cg_cgroup_link
crash> css_set.cg_links 0xffff8f47e5a20cc0
  cg_links = {
    next = 0xffff8f478cc40518, 
    prev = 0xffff8f478cc404d8
  }

# 注意,这里取到的不是cg_cgroup_link的地址,是cg_cgroup_link.cg_link_list
crash> struct -o css_set.cg_links 0xffff8f47e5a20cc0
struct css_set {
  [ffff8f47e5a20ce8] struct list_head cg_links;
}

# 可以看到进程关联了12个cg_cgroup_link
crash> list -H ffff8f47e5a20ce8 | wc -l
12

# task-> css_set-> cg_cgroup_link -> cgroup
# 获取到cgroup = 0xffffffff9c464520
crash> list -l cg_cgroup_link.cg_link_list -s cg_cgroup_link.cgrp -H ffff8f47e5a20ce8
ffff8f478cc40518
  cgrp = 0xffffffff9c93d030
ffff8f478cc40858
  cgrp = 0xffff8f4786b98c00
ffff8f478cc40a58
  cgrp = 0xffff8f48753f2030
ffff8f478cc40158
  cgrp = 0xffff8f487b226030
ffff8f478cc40c58
  cgrp = 0xffff8f487b222030
ffff8f478cc402d8
  cgrp = 0xffff8f487b220030
ffff8f478cc400d8
  cgrp = 0xffff8f487b224030
ffff8f478cc40d18
  cgrp = 0xffff8f4872406030
ffff8f478cc40498
  cgrp = 0xffff8f4872404030
ffff8f478cc40258
  cgrp = 0xffff8f4872402030
ffff8f478cc40318
  cgrp = 0xffff8f4776836800 # 	get!!
ffff8f478cc404d8
  cgrp = 0xffff8f487246c030

获取cgroup对应的task

前面知道, 由task到cgroup有两条路径。但是,虽然可以通过cgroup查看到关联的css,但是由于css与cgroup是多对多关系,并且css和task也是多对多的关系,所以通过css没办法直接获取到cgroup对应的task。所以内核引入了cg_cgroup_link来关联。

具体路径为:cgroup -> cg_cgroup_link -> css_set -> task

由上文获取到的cgroup[0xffff8f4776836800] 为例,获取task

# 查看与cgroup关联的css数组*subsys[]
# 可以看到只关联了一个css,即对应一个子系统 
crash> cgroup.subsys 0xffff8f4776836800
  subsys = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff8f47e9f93720, 0x0}

# 要获取task,需要通过一个中间结构cg_cgroup_link (此处参考3.10.x版本,5.x版本这部分结构有变动)
# cgroup -> cg_cgroup_link
# cgroup.css_sets指向cgroup对应的所有cg_cgroup_link链表,可以看到这个cgroup对应的链表只有一个节点
crash> cgroup.css_sets 0xffff8f4776836800
  css_sets = {
    next = 0xffff8f478cc40300, 
    prev = 0xffff8f478cc40300
  }

crash> struct -o cgroup.css_sets 0xffff8f4776836800
struct cgroup {
  [ffff8f47768368c0] struct list_head css_sets;
}

# cgroup -> cg_cgroup_link -> css_set
crash> list -l cg_cgroup_link.cgrp_link_list -s cg_cgroup_link -H ffff8f47768368c0
ffff8f478cc40300
struct cg_cgroup_link {
  cgrp_link_list = {				# 指向cgroup.css_sets(即包含该cg_cgroup_link的链表)用于直接遍历该cgroup的所有cg_cgroup_link(得到css_sets)
    next = 0xffff8f47768368c0, 
    prev = 0xffff8f47768368c0
  }, 
  cgrp = 0xffff8f4776836800, 		# 指向cg_cgroup_link关联的cgroup
  cg_link_list = {					# 指向css_set.cg_links,用于遍历该css_set关联的所有cg_cgroup_link(得到所有cgroup)
    next = 0xffff8f478cc404d8, 
    prev = 0xffff8f478cc40258
  }, 
  cg = 0xffff8f47e5a20cc0			# 指向cg_cgroup_link关联的css_set
}

# cgroup -> cg_cgroup_link -> css_set [-> css_set.tasks]
crash> css_set.tasks 0xffff8f47e5a20cc0
  tasks = {
    next = 0xffff8f47f5166c48, 
    prev = 0xffff8f47f5166c48
  }

# cgroup -> cg_cgroup_link -> css_set [-> css_set.tasks -> task_struct.cg_list]
crash> list -H 0xffff8f47f5166c48
ffff8f47e5a20cd8

# cgroup -> cg_cgroup_link -> css_set -> task
crash> list -l task_struct.cg_list -s task_struct.pid -H ffff8f47e5a20cd8
ffff8f47f5166c48
  pid = 6997

获取css_set对应的task_struct

两者的关系如下图
在这里插入图片描述
task_struct和css_set 通过cg_list和tasks互相关联

crash> task -R cg_list 6997
PID: 6997   TASK: ffff8f47f5166300  CPU: 1   COMMAND: "sleep"
  cg_list = {
    next = 0xffff8f47e5a20cd8, 
    prev = 0xffff8f47e5a20cd8
  }, 

crash> list -H 0xffff8f47e5a20cd8
ffff8f47f5166c48


crash> task -R cgroups 6997
PID: 6997   TASK: ffff8f47f5166300  CPU: 1   COMMAND: "sleep"
  cgroups = 0xffff8f47e5a20cc0, 

crash> css_set.tasks 0xffff8f47e5a20cc0
  tasks = {
    next = 0xffff8f47f5166c48, 
    prev = 0xffff8f47f5166c48
  }

crash> list -H 0xffff8f47f5166c48
ffff8f47e5a20cd8


# 通过计算偏移量获取css_set.cg_list对应的task_struct地址
crash> list -l task_struct.cg_list -s task_struct  -H ffff8f47e5a20cd8
ffff8f47f5166c48
struct task_struct {
  state = 1, 
  stack = 0xffff8f48767c0000, 
  usage = {
    counter = 2
    ... ...
# 获取到css_set对应的task
crash> list -l task_struct.cg_list -s task_struct.group_leader -H ffff8f47e5a20cd8
ffff8f47f5166c48
  group_leader = 0xffff8f47f5166300

【参考】

[结构关系图]https://blog.csdn.net/hu1610552336/article/details/118642410
[crash实例] http://linux.laoqinren.net/kernel/cgroup-source-css_set-and-cgroup/#css_set%E5%92%8Ccgroup%E4%B9%8B%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值