Crash Tool로 커널 오브젝트의 rbtree를 디버깅해서 parent node를 확인하는 방법에 대해 간단히 소개하고자 해요.
아래와 같은 커널 오브젝트가 있다고 가정해보아요. Sys node의 위치는 /sys/devices/system/cpu/cpu3 이겠죠?
현재 struct kobject->cpu는 "cpu3"을 가르키고 있는데요, 그럼 이 커널 오브젝트의 상위 directory는 어떻게 검색할 수 있을까요?
(struct kobject *) (struct kobject *)0xDEF78018 = 0xDEF78018 -> (
(char *) name = 0xDE211780 -> "cpu3",
(struct list_head) entry = ((struct list_head *) next = 0xDEF8401C, (struct list_head *) prev = 0x
(struct kobject *) parent = 0xDEADA288,
(struct kset *) kset = 0xDEAF6540,
(struct kobj_type *) ktype = 0xC12E9DF0,
(struct kernfs_node *) sd = 0xDE213240 -> (
(atomic_t) count = ((int) counter = 12 = 0x0C),
(atomic_t) active = ((int) counter = 0 = 0x0),
(struct kernfs_node *) parent = 0xDEADBC00,
(char *) name = 0xDE211840 -> "cpu3",
(struct rb_node) rb = (
(long unsigned int) __rb_parent_color = 3735926096 = 0xDEADB550,
(struct rb_node *) rb_right = 0xDE215C10,
(struct rb_node *) rb_left = 0xDE2069D0),
역시 crash tool에서 rbtree를 파싱할 수 있는 기능을 제공해요.
struct kobject->sd가 갖고 있는 0xDE213240 인스턴스로 parent directory에 대한 rb_node가 있는 struct kernfs_node->rb에 접근이 가능하거든요.
crash> tree -t rbtree -o kernfs_node.rb -N 0xDE213240
de213230
deadbbf0
de862470
de862cb0
de861ff0
위 Output 값은 뭘 의미할까요? 좀 복잡한데요.
아래 struct kernfs_node 구조체를 보면 struct kernfs_elem_attr attr 멤버가 보이죠?
위 Output은 struct kernfs_elem_attr가 위치한 주소를 가르키고 있거든요.
struct kernfs_elem_attr->notify_next 오프셋이 0x10이니 0x10만큼 더해줘야 해요.
struct kernfs_elem_attr {
const struct kernfs_ops *ops;
struct kernfs_open_node *open;
loff_t size;
struct kernfs_node *notify_next;
};
(where)
struct kernfs_node {
atomic_t count;
atomic_t active;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
// .. 생략..
union {
struct kernfs_elem_dir dir;
struct kernfs_elem_symlink symlink;
struct kernfs_elem_attr attr;
};
.
뭔 소리인지 모르겠다구요? 커널 오브젝트로 디렉토리를 아래 콜 트레이스로 등록되거든요.
나중에 상세 분석할 시간을 갖도록 할께요. 핵심 함수는 kernfs_create_dir_ns/kernfs_new_node 이에요.
\\vmlinux\kernfs/dir\__kernfs_new_node+0x60
\\vmlinux\slub\kmem_cache_alloc+0x254
\\vmlinux\kernfs/dir\__kernfs_new_node+0x60
\\vmlinux\kernfs/dir\kernfs_new_node+0x2C
\\vmlinux\kernfs/dir\kernfs_create_dir_ns+0x28
\\vmlinux\sysfs/dir\sysfs_create_dir_ns+0x5C
\\vmlinux\kobject\kobject_add_internal+0xAC
\\vmlinux\kobject\kobject_add+0x50
\\vmlinux\base/core\device_add+0x11C
이제 확인할 시간이에요.
(struct kernfs_node *)(0xde213230+0x10) = 0xDE213240 -> (
count = (counter = 12),
active = (counter = 0),
parent = 0xDEADBC00,
name = 0xDE211840 -> "cpu3",
(struct kernfs_node *)(0xdeadbbf0+0x10) = 0xDEADBC00 -> (
count = (counter = 23),
active = (counter = 0),
parent = 0xDE862480,
name = 0xDEAD96C0 -> "cpu",
(struct kernfs_node *)(0xde862470+0x10) = 0xDE862480 -> (
count = (counter = 9),
active = (counter = 0),
parent = 0xDE862CC0,
name = 0xDEAD7480 -> "system",
(struct kernfs_node *)(0xde862cb0+0x10) = 0xDE862CC0 -> (
count = (counter = 36),
active = (counter = 0),
parent = 0xDE862000,
name = 0xDEAF6600 -> "devices",
상위 디렉토리가 이렇게 확인 가능하군요.
/sys/devices/system/cpu/cpu3
'[Debugging] Tips' 카테고리의 다른 글
Trace32 유용한 명령어 - y.b (0) | 2023.05.04 |
---|---|
커널 오브젝트 Kernel Object - rbtree debugging(child directory) - (1) (0) | 2023.05.04 |
IPI (Inter Processor Interrupts) 소개 및 디버깅 패치 (1) (0) | 2023.05.04 |
[crash-utility]wakelock - rbtree debugging(디버깅) (0) | 2023.05.04 |
crash-utility(crash tool) - ps command (0) | 2023.05.04 |