Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

740
557
422269


IRQ Stack(ARM64) - Debugging(디버깅) [Linux][Kernel] MM

아래 블로그에서 IRQ Stack(ARM64)에 대해 소개를 했는데요.
http://rousalome.egloos.com/9966360

이번에는 직접 코어 덤프에서 IRQ Stack 덤프를 살펴볼께요.

IRQ Stack Feature를 지원하는 프로세스의 콜스택을 Trace32로 잡아서 확인해 보았어요.
참고로, 아래는 CPU0에서 idle process가 돌아가 갑자기 IRQ가 Trigger되었을 시의 동작이에요.
-000|gic_handle_irq(?)
-001|el1_irq(asm)
 -->|exception
-002|lpm_cpuidle_enter(dev = 0x0, ?, idx = 0)
-003|cpuidle_enter_state(dev = 0xFFFFFFE57E2A33D8, drv = 0xFFFFFFE4F2E14C00, index = 0)
-004|cpuidle_enter(drv = 0xFFFFFFE4F2E14C00, ?, ?)
-005|call_cpuidle(inline)
-005|cpuidle_idle_call(inline)
-005|cpu_idle_loop(inline)
-005|cpu_startup_entry(?)
-006|rest_init()
-007|start_kernel()

우선 per-cpu 타입의 irq_stack 변수를 살펴볼 필요가 있는데요. 아래 명령어로 0xFFFFFF9F9B227060 주소라는 것을 알 수 있어요.
v.v %l &irq_stack
  [-] &irq_stack = 0xFFFFFF9F9B227060

아래 공식을 대입하면, 결과는? 0xFFFFFFE57E29E060이군요.
irq_stack + __per_cpu_offset[0] + IRQ Stack Size  
0xFFFFFFE57E29E060 = 0xFFFFFF9F9B227060 + 0x00000045E3073000 + 0x4000
v.v %h %i %d  __per_cpu_offset  
  __per_cpu_offset = (
    [0] = 300161642496 = 0x00000045E3073000,
    [1] = 300161728512 = 0x00000045E3088000,
    [2] = 300161814528 = 0x00000045E309D000,
    [3] = 300161900544 = 0x00000045E30B2000,
    [4] = 300161986560 = 0x00000045E30C7000,
    [5] = 300162072576 = 0x00000045E30DC000,
    [6] = 300162158592 = 0x00000045E30F1000,
    [7] = 300162244608 = 0x00000045E3106000)
0xFFFFFFE57E29E060 주소가 CPU0의 IRQ Stack 주소이군요.
_____________address|_data____________________|value_____________|symbol
NSD:FFFFFFE57E29DFF0| 40 E0 29 7E E5 FF FF FF  0xFFFFFFE57E29E040
NSD:FFFFFFE57E29DFF8| 1C 29 68 99 9F FF FF FF  0xFFFFFF9F9968291C \\vmlinux\Global\el1_irq+0xDC
NSD:FFFFFFE57E29E000| D0 3C AE 9B 9F FF FF FF  0xFFFFFF9F9BAE3CD0 \\vmlinux\Global\init_thread_union+0x3CD0
NSD:FFFFFFE57E29E008| 00 00 00 00 80 00 00 00  0x8000000000
NSD:FFFFFFE57E29E010| 00 30 BA 82 00 00 00 00  0x82BA3000
NSD:FFFFFFE57E29E018| 0C 28 08 9A 9F FF FF FF  0xFFFFFF9F9A08280C \\vmlinux\lpm-levels\lpm_cpuidle_enter\exit+0x224
NSD:FFFFFFE57E29E020| 45 01 40 60 00 00 00 00  0x60400145
NSD:FFFFFFE57E29E028| 00 70 AF 9B 9F FF FF FF  0xFFFFFF9F9BAF7000 \\vmlinux\trace/ftrace\ftrace_func_hash+0x278
NSD:FFFFFFE57E29E030| 60 A0 29 7E E5 FF FF FF  0xFFFFFFE57E29A060
NSD:FFFFFFE57E29E038| 50 E0 29 7E E5 FF FF FF  0xFFFFFFE57E29E050
NSD:FFFFFFE57E29E040| 00 3E AE 9B 9F FF FF FF  0xFFFFFF9F9BAE3E00 // IRQ가 Trigger되기 전에 돌던 프로세스의 스택 주소
NSD:FFFFFFE57E29E048| D0 3C AE 9B 9F FF FF FF  0xFFFFFF9F9BAE3CD0 \\vmlinux\Global\init_thread_union+0x3CD0
NSD:FFFFFFE57E29E050| 00 00 00 00 00 00 00 00  0x0
NSD:FFFFFFE57E29E058| 00 00 00 00 00 00 00 00  0x0
NSD:FFFFFFE57E29E060| A0 38 80 52 E5 FF FF FF  0xFFFFFFE5528038A0 //<<-- CPU0의 IRQ Stack bottom 주소

IRQ가 뜨기 전에 CPU0에서 돌던 swapper/0 프로세스의 스택은 아래와 같아요.
담쟁이 덩굴같이 자라나는 ARM64 Calling Convention 규칙으로 콜 트래이스를 점검할 수 있수 있는데요. 아래 볼드체로 되어 있는 주소를 유심히 보세요. 
_____________address|_data____________________|value_____________|symbol
NSD:FFFFFF9F9BAE3E00| 70 3E AE 9B 9F FF FF FF  0xFFFFFF9F9BAE3E70 \\vmlinux\Global\init_thread_union+0x3E70
NSD:FFFFFF9F9BAE3E08| 40 C2 07 9A 9F FF FF FF  0xFFFFFF9F9A07C240 \\vmlinux\cpuidle/cpuidle\cpuidle_enter_state+0x18C
NSD:FFFFFF9F9BAE3E10| 18 4C E1 F2 E4 FF FF FF  0xFFFFFFE4F2E14C18
NSD:FFFFFF9F9BAE3E18| 00 00 00 00 00 00 00 00  0x0
NSD:FFFFFF9F9BAE3E20| 28 7B D6 9B 9F FF FF FF  0xFFFFFF9F9BD67B28 \\vmlinux\Global\__tracepoint_cpu_idle
NSD:FFFFFF9F9BAE3E28| D8 33 2A 7E E5 FF FF FF  0xFFFFFFE57E2A33D8
NSD:FFFFFF9F9BAE3E30| 00 4C E1 F2 E4 FF FF FF  0xFFFFFFE4F2E14C00
NSD:FFFFFF9F9BAE3E38| 00 00 00 00 00 00 00 00  0x0
NSD:FFFFFF9F9BAE3E40| 6C 35 81 F3 07 00 00 00  0x7F381356C
NSD:FFFFFF9F9BAE3E48| 00 10 BA 82 00 00 00 00  0x82BA1000
NSD:FFFFFF9F9BAE3E50| 28 7B D6 9B 9F FF FF FF  0xFFFFFF9F9BD67B28 \\vmlinux\Global\__tracepoint_cpu_idle
NSD:FFFFFF9F9BAE3E58| 90 01 B3 81 00 00 00 00  0x81B30190
NSD:FFFFFF9F9BAE3E60| 20 F2 8D F3 07 00 00 00  0x7F38DF220
NSD:FFFFFF9F9BAE3E68| 00 00 23 9B 9F FF FF FF  0xFFFFFF9F9B230000 \\vmlinux\scsi_logging\scsi_format_log+0xE70
NSD:FFFFFF9F9BAE3E70| D0 3E AE 9B 9F FF FF FF  0xFFFFFF9F9BAE3ED0 \\vmlinux\Global\init_thread_union+0x3ED0
NSD:FFFFFF9F9BAE3E78| 38 C4 07 9A 9F FF FF FF  0xFFFFFF9F9A07C438 \\vmlinux\cpuidle/cpuidle\cpuidle_enter+0x34
NSD:FFFFFF9F9BAE3E80| 00 4C E1 F2 E4 FF FF FF  0xFFFFFFE4F2E14C00
NSD:FFFFFF9F9BAE3E88| 00 4C E1 F2 E4 FF FF FF  0xFFFFFFE4F2E14C00
NSD:FFFFFF9F9BAE3E90| 38 BC 22 9B 9F FF FF FF  0xFFFFFF9F9B22BC38 \\vmlinux\Global\cpu_dead_idle
NSD:FFFFFF9F9BAE3E98| D0 03 23 9B 9F FF FF FF  0xFFFFFF9F9B2303D0 \\vmlinux\Global\cpuidle_devices
NSD:FFFFFF9F9BAE3EA0| 00 00 AE 9B 9F FF FF FF  0xFFFFFF9F9BAE0000 \\vmlinux\Global\init_thread_union
NSD:FFFFFF9F9BAE3EA8| 00 60 AF 9B 9F FF FF FF  0xFFFFFF9F9BAF6000 \\vmlinux\Global\nf_conntrack_locks+0xA00
NSD:FFFFFF9F9BAE3EB0| 80 4E 34 7E E5 FF FF FF  0xFFFFFFE57E344E80
NSD:FFFFFF9F9BAE3EB8| 00 10 BA 82 00 00 00 00  0x82BA1000
NSD:FFFFFF9F9BAE3EC0| 70 00 23 81 00 00 00 00  0x81230070
NSD:FFFFFF9F9BAE3EC8| 00 4C E1 F2 E4 FF FF FF  0xFFFFFFE4F2E14C00
NSD:FFFFFF9F9BAE3ED0| 00 3F AE 9B 9F FF FF FF  0xFFFFFF9F9BAE3F00 \\vmlinux\Global\init_thread_union+0x3F00
NSD:FFFFFF9F9BAE3ED8| 84 5B 6F 99 9F FF FF FF  0xFFFFFF9F996F5B84 \\vmlinux\idle\cpu_startup_entry+0x2D0
NSD:FFFFFF9F9BAE3EE0| D8 33 2A 7E E5 FF FF FF  0xFFFFFFE57E2A33D8
NSD:FFFFFF9F9BAE3EE8| CC 5A 6F 99 9F FF FF FF  0xFFFFFF9F996F5ACC \\vmlinux\idle\cpu_startup_entry+0x218
NSD:FFFFFF9F9BAE3EF0| D8 33 2A 7E E5 FF FF FF  0xFFFFFFE57E2A33D8
NSD:FFFFFF9F9BAE3EF8| 00 00 00 00 00 00 00 00  0x0
NSD:FFFFFF9F9BAE3F00| 60 3F AE 9B 9F FF FF FF  0xFFFFFF9F9BAE3F60 \\vmlinux\Global\init_thread_union+0x3F60
NSD:FFFFFF9F9BAE3F08| 8C 69 82 9A 9F FF FF FF  0xFFFFFF9F9A82698C \\vmlinux\init/main\rest_init+0x88
NSD:FFFFFF9F9BAE3F10| 00 00 90 83 00 00 00 00  0x83900000
NSD:FFFFFF9F9BAE3F18| 00 60 AF 9B 9F FF FF FF  0xFFFFFF9F9BAF6000 \\vmlinux\Global\nf_conntrack_locks+0xA00
NSD:FFFFFF9F9BAE3F20| 00 A0 D7 9B 9F FF FF FF  0xFFFFFF9F9BD7A000 \\vmlinux\Global\reset_devices
NSD:FFFFFF9F9BAE3F28| 00 00 AE 9B 9F FF FF FF  0xFFFFFF9F9BAE0000 \\vmlinux\Global\init_thread_union
NSD:FFFFFF9F9BAE3F30| 00 A0 D7 9B 9F FF FF FF  0xFFFFFF9F9BD7A000 \\vmlinux\Global\reset_devices
NSD:FFFFFF9F9BAE3F38| 00 60 AF 9B 9F FF FF FF  0xFFFFFF9F9BAF6000 \\vmlinux\Global\nf_conntrack_locks+0xA00
NSD:FFFFFF9F9BAE3F40| 80 4E 34 7E E5 FF FF FF  0xFFFFFFE57E344E80
NSD:FFFFFF9F9BAE3F48| 00 10 BA 82 00 00 00 00  0x82BA1000
NSD:FFFFFF9F9BAE3F50| 00 00 90 83 00 00 00 00  0x83900000
NSD:FFFFFF9F9BAE3F58| C0 01 B1 9B 9F FF FF FF  0xFFFFFF9F9BB101C0 \\vmlinux\Global\init_pid_ns
NSD:FFFFFF9F9BAE3F60| 80 3F AE 9B 9F FF FF FF  0xFFFFFF9F9BAE3F80 \\vmlinux\Global\init_thread_union+0x3F80
NSD:FFFFFF9F9BAE3F68| 20 0C 13 9B 9F FF FF FF  0xFFFFFF9F9B130C20 \\vmlinux\init/main\start_kernel+0x424
NSD:FFFFFF9F9BAE3F70| 00 A0 D7 9B 9F FF FF FF  0xFFFFFF9F9BD7A000 \\vmlinux\Global\reset_devices
NSD:FFFFFF9F9BAE3F78| 02 00 00 00 00 00 00 00  0x2
NSD:FFFFFF9F9BAE3F80| 00 00 00 00 00 00 00 00  0x0

볼드체로 되어 있는 심볼 정보가 아래 콜스택과 동일하죠?
-000|gic_handle_irq(?)
-001|el1_irq(asm)
 -->|exception
-002|lpm_cpuidle_enter(dev = 0x0, ?, idx = 0)
-003|cpuidle_enter_state(dev = 0xFFFFFFE57E2A33D8, drv = 0xFFFFFFE4F2E14C00, index = 0)
-004|cpuidle_enter(drv = 0xFFFFFFE4F2E14C00, ?, ?)
-005|call_cpuidle(inline)
-005|cpuidle_idle_call(inline)
-005|cpu_idle_loop(inline)
-005|cpu_startup_entry(?)
-006|rest_init()
-007|start_kernel()




덧글

댓글 입력 영역