• crash命令 —— list


    参考:
    https://crash-utility.github.io/help_pages/list.html

    笔记:

    头节点是A_head:
    
    struct A_head {                     // -h
        ...                             // -O
        struct list_head list;          // -H
        int b;                          // -s
    };
    
    普通节点是A:
    
    struct A {                          // -h
        ...                             // -o
        struct list_head list;          // -H
        char pid;                       // -s
    };
    
    假设将来A通过A.node挂到A_head.
    
    -H: list的地址
    -h: A_head或者A的地址
    -o: 在普通节点中list在A中的偏移,格式A.list
    -O: 在头结点中list在A中的偏移,格式A_head.list。当头节点跟普通节点不同的时候需要这个参数,在输出的内容里不会输出头节点的内容。
    -s: 要查看的结构体的成员
    

    示例

    • 遍历线程组thread_group
      当创建线程的时候,当前进程下的所有线程的task_struct都通过thread_node挂在了task_struct->signal->thread_head下面。
    	list_add_tail_rcu(&p->thread_group,
    		  &p->group_leader->thread_group);
    	list_add_tail_rcu(&p->thread_node,
    		  &p->signal->thread_head);
    

    线程组中的task的signal是相同的,所以先获取signal的地址,然后遍历thread_head链表即可。

    以task 714为例:

    crash> task -R signal 714
    PID: 714    TASK: ffff889e1449c000  CPU: 14  COMMAND: "kvm"
      signal = 0xffff889ecdaab600,
    

    然后查看thread_head的地址:

    crash> signal_struct.nr_threads,thread_head 0xffff889ecdaab600
      nr_threads = 17
      thread_head = {
        next = 0xffff889ecd9789b8,
        prev = 0xffff88a031cf89b8
      }
    

    当前线程组有17个线程,开始遍历:

    crash> list -o task_struct.thread_node -s task_struct.pid,tgid -H ffff889ecdaab610
    ffff889ecd978000
      pid = 451
      tgid = 451
    ffff889ed1c44000
      pid = 452
      tgid = 451
    ffff8899f8bb2000
      pid = 456
      tgid = 451
    ffff8897bc884000
      pid = 480
      tgid = 451
    ffff8897bc880000
      pid = 487
      tgid = 451
    ffff8897bc882000
      pid = 488
      tgid = 451
    ffff8897bc886000
    ...
    
    • 遍历cgroup_root

    • 以下面的数据结构关系为例:
      image

    说明:

    • head_node使用head_list连接到list_head_test中
    • head_node之间有父子关系
    • head_node的node通过node.list连到head_node.node_list下面
    • 所有的node通过node.slib连接在一起
    1. 查看list_head_test地址
    crash> sym list_head_test
    ffffffffad245b30 (d) list_head_test
    
    1. 查看list_head_test链表下挂的head_node
    crash> list -o head_node.head_list -s head_node.name -H ffffffffad245b30
    ffff93b2850c3b40  // struct head_node的地址
      name = 0xfffffffface7a68f "head1",
    ffff93b2850c3b80  // struct head_node的地址
      name = 0xfffffffface7a695 "head2",
    ffff93b2850c3bc0  // struct head_node的地址
      name = 0xfffffffface7a69b "head3",
    
    1. 查看head1parent
    crash> list -o head_node.parent -s head_node.name ffff93b2850c3b40
    ffff93b2850c3b40
      name = 0xfffffffface7a68f "head1",
    ffff93b2850c3b80
      name = 0xfffffffface7a695 "head2",
    ffff93b2850c3bc0
      name = 0xfffffffface7a69b "head3",
    

    在结构体中,parent没有采用list_head链表,所以不能用-h或者-H

    1. 查看head_node1下的node成员
    crash> list -o node.list -s node.name -O head_node.node_list -h ffff93b2850c3b40
    ffff93b2850c3c00
      name = 0xfffffffface7a6a1 "node1",
    ffff93b2850c3c40
      name = 0xfffffffface7a6a7 "node2",
    ffff93b2850c3c80
      name = 0xfffffffface7a6ad "node3",
    
    1. 查看head_node2下的node成员
    crash> list -o node.list -s node.name -O head_node.node_list -h ffff93b2850c3b80
    ffff93b2850c3cc0
      name = 0xfffffffface7a6b3 "node4",
    ffff93b2850c3d00
      name = 0xfffffffface7a6b9 "node5",
    ffff93b2850c3d40
      name = 0xfffffffface7a6bf "node6",
    
    1. 查看head_node3下的node成员
    crash> list -o node.list -s node.name -O head_node.node_list -h ffff93b2850c3bc0
    ffff93b2850c3d80
      name = 0xfffffffface7a6c5 "node7",
    ffff93b2850c3dc0
      name = 0xfffffffface7a6cb "node8",
    ffff93b2850c3e00
      name = 0xfffffffface7a6d1 "node9",
    
    1. 查看node.slib链表中的成员

    使用node1的起始地址

    crash> list -o node.slib -s node.name -h ffff93b2850c3c00
    ffff93b2850c3c00
      name = 0xfffffffface7a6a1 "node1",
    ffff93b2850c3c40
      name = 0xfffffffface7a6a7 "node2",
    ffff93b2850c3c80
      name = 0xfffffffface7a6ad "node3",
    ffff93b2850c3cc0
      name = 0xfffffffface7a6b3 "node4",
    ffff93b2850c3d00
      name = 0xfffffffface7a6b9 "node5",
    ffff93b2850c3d40
      name = 0xfffffffface7a6bf "node6",
    ffff93b2850c3d80
      name = 0xfffffffface7a6c5 "node7",
    ffff93b2850c3dc0
      name = 0xfffffffface7a6cb "node8",
    ffff93b2850c3e00
      name = 0xfffffffface7a6d1 "node9",
    

    如果使用-O参数,那么会把传入地址当作头节点,输出的内容不包含头节点的内容:

    crash> list -o node.slib -s node.name  -O node.slib -h ffff93b2850c3c00
    ffff93b2850c3c40
      name = 0xfffffffface7a6a7 "node2",
    ffff93b2850c3c80
      name = 0xfffffffface7a6ad "node3",
    ffff93b2850c3cc0
      name = 0xfffffffface7a6b3 "node4",
    ffff93b2850c3d00
      name = 0xfffffffface7a6b9 "node5",
    ffff93b2850c3d40
      name = 0xfffffffface7a6bf "node6",
    ffff93b2850c3d80
      name = 0xfffffffface7a6c5 "node7",
    ffff93b2850c3dc0
      name = 0xfffffffface7a6cb "node8",
    ffff93b2850c3e00
      name = 0xfffffffface7a6d1 "node9",
    
  • 相关阅读:
    模块3 re + 正则表达式
    模块2
    模块1
    super
    MRO,C3算法
    日志,固定格式
    异常处理,MD5
    类的约束
    反射
    异常处理MR5
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/16046328.html
Copyright © 2020-2023  润新知