리눅스 커널 데이터 스트럭쳐 내 수 많은 linked list를 확인할 수 있어요.
예를 들어 struct kset이란 구조체도 첫번 째 멤버로 list란 링크드 리스트죠.
struct kset {
struct list_head list; //<<--
spinlock_t list_lock;
struct kobject kobj;
const struct kset_uevent_ops *uevent_ops;
};
실제 코어 덤프를 T32로 열어서 상세 구조체를 보면 아래와 같거든요.
kset_find_obj(
[R5] kset = 0xED74A980 -> (
[NSD:0xED74A980] list = ( //<<--
[NSD:0xED74A980] next = 0xED751104 -> (
[NSD:0xED751104] next = 0xED5A4404,
[NSD:0xED751108] prev = 0xED74A980),
[NSD:0xED74A984] prev = 0xEC3A7384),
[NSD:0xED74A988] list_lock = ([NSD:0xED74A988] rlock = ([NSD:0xED74A988] raw_lock = ([NSD:0xED
[NSD:0xED74A998] kobj = ([NSD:0xED74A998] name = 0xED74A9C0, [NSD:0xED74A99C] entry = ([NSD:0x
[NSD:0xED74A9BC] uevent_ops = 0x0),
[R7] name = 0xC1C33FB8)
그런데 T32에서는 Linked List를 좀 더 비쥬얼하게 트리 형태로 볼 수 있는 아주 훌륭한 명령어가 있거든요.
자 그럼 _fake_list_sym.cmm이란 이름으로 T32 cmm script를 만들어볼까요?
원리는 간단해요. __pompeii_list_head 란 가상 심볼을 만들어서 링크드 리스트를 표현하는 거죠.
ENTRY &list_address
// create fake list symbol
y.create.var __pompeii_list_head 0 struct list_head
y.create.done
symbol.modify.address __pompeii_list_head &list_address
v.v __pompeii_list_head
v.chain %m %l %tree.open %hex __pompeii_list_head __pompeii_list_head.next
자 이제 위 스크립트를 _fake_list_sym.cmm로 저장하구요,
Linked List가 위치한 주소를 아규먼트로 입력합니다.
do _fake_list.sym 0xED74A980
(where)
kset_find_obj(
[R5] kset = 0xED74A980 -> (
[NSD:0xED74A980] list = ( //<<--
[NSD:0xED74A980] next = 0xED751104 -> (
짜잔, 이제 결과는? 아래와 같이 출력되는데요. 음, 111 번째 링크드 리스트 멤버가 깨져 있네요.
이런 스크립트를 안 쓰면 좀 디버깅이 불편하죠.
0x0 (0)| [C:0xED74A980] (
| [C:0xED74A980] next = 0xED751104,
| [C:0xED74A984] prev = 0xEC3A7384),
0x1 (1)| [C:0xED751104] (
| [C:0xED751104] next = 0xED5A4404,
| [C:0xED751108] prev = 0xED74A980),
0x2 (2)| [C:0xED5A4404] (
| [C:0xED5A4404] next = 0xED5A4E84,
| [C:0xED5A4408] prev = 0xED751104),
0x3 (3)| [C:0xED5A4E84] (
| [C:0xED5A4E84] next = 0xED5A4F04,
| [C:0xED5A4E88] prev = 0xED5A4404),
0x4 (4)| [C:0xED5A4F04] (
| [C:0xED5A4F04] next = 0xED5A4F84,
| [C:0xED5A4F08] prev = 0xED5A4E84),
0x5 (5)| [C:0xED5A4F84] (
| [C:0xED5A4F84] next = 0xED760204,
| [C:0xED5A4F88] prev = 0xED5A4F04),
0x6 (6)| [C:0xED760204] (
| [C:0xED760204] next = 0xED175F84,
| [C:0xED760208] prev = 0xED5A4F84),
0x7 (7)| [C:0xED175F84] (
| [C:0xED175F84] next = 0xED198004,
| [C:0xED175F88] prev = 0xED760204),
0x8 (8)| [C:0xED198004] (
| [C:0xED198004] next = 0xED198184,
| [C:0xED198008] prev = 0xED175F84),
0x9 (9)| [C:0xED198184] (
| [C:0xED198184] next = 0xED198204,
| [C:0xED198188] prev = 0xED198004),
0x0A (10)| [C:0xED198204] (
| [C:0xED198204] next = 0xED198284,
| [C:0xED198208] prev = 0xED198184),
0x0B (11)| [C:0xED198284] (
| [C:0xED198284] next = 0xED198304,
| [C:0xED198288] prev = 0xED198204),
0x0C (12)| [C:0xED198304] (
| [C:0xED198304] next = 0xED198404,
| [C:0xED198308] prev = 0xED198284),
0x0D (13)| [C:0xED198404] (
| [C:0xED198404] next = 0xED198484,
| [C:0xED198408] prev = 0xED198304),
0x0E (14)| [C:0xED198484] (
| [C:0xED198484] next = 0xED198904,
| [C:0xED198488] prev = 0xED198404),
0x0F (15)| [C:0xED198904] (
| [C:0xED198904] next = 0xED1BAC04,
| [C:0xED198908] prev = 0xED198484),
0x10 (16)| [C:0xED1BAC04] (
| [C:0xED1BAC04] next = 0xED142E04,
| [C:0xED1BAC08] prev = 0xED198904),
0x11 (17)| [C:0xED142E04] (
| [C:0xED142E04] next = 0xED142E84,
| [C:0xED142E08] prev = 0xED1BAC04),
0x12 (18)| [C:0xED142E84] (
| [C:0xED142E84] next = 0xED142F04,
| [C:0xED142E88] prev = 0xED142E04),
0x13 (19)| [C:0xED142F04] (
| [C:0xED142F04] next = 0xED142F84,
| [C:0xED142F08] prev = 0xED142E84),
0x14 (20)| [C:0xED142F84] (
| [C:0xED142F84] next = 0xED145184,
| [C:0xED142F88] prev = 0xED142F04),
//snip
x6A (106)| [C:0xECD3DE04] (
| [C:0xECD3DE04] next = 0xECF04184,
| [C:0xECD3DE08] prev = 0xECD3D604),
x6B (107)| [C:0xECF04184] (
| [C:0xECF04184] next = 0xECE1DE84,
| [C:0xECF04188] prev = 0xECD3DE04),
x6C (108)| [C:0xECE1DE84] (
| [C:0xECE1DE84] next = 0xECE1DF04,
| [C:0xECE1DE88] prev = 0xECF04184),
x6D (109)| [C:0xECE1DF04] (
| [C:0xECE1DF04] next = 0xECE1DF84,
| [C:0xECE1DF08] prev = 0xECE1DE84),
x6E (110)| [C:0xECE1DF84] (
| [C:0xECE1DF84] next = 0xECDDC004, //<<--
| [C:0xECE1DF88] prev = 0xECE1DF04),
x6F (111)| [C:0xECDDC004] (
| [C:0xECDDC004] next = 0xECDDC09F, //<<--
| [C:0xECDDC008] prev = 0xECE1DF9F),
x70 (112)| [C:0xECDDC09F] ( //<<--
| [C:0xECDDC09F] next = 0x0700, //<<--
| [C:0xECDDC0A3] prev = 0x01000100),
x71 (113)| [C:0x700] (
| [C:0x700] next = 0x0,
| [C:0x704] prev = 0x0),
'[Debugging] Tips' 카테고리의 다른 글
[Linux][Kernel] T32 - 구조체 확인 (v.type) (0) | 2023.05.05 |
---|---|
[Linux][Kernel] 전처리 Preprocess File 추출 방법 (0) | 2023.05.04 |
[리눅스커널][디버깅] Red Hat Crash-Utility(크래시 유틸리티) 설치 (0) | 2023.05.04 |
[Linux][Kernel][ARM] char buf[32]; vs char buf[32]={0}; (0) | 2023.05.04 |
[Linux][Kernel] ftrace: stack tracer (0) | 2023.05.04 |