유저 공간에서 시스템 콜을 호출할 때 유저 공간에서 돌던 레지스터를 커널 공간 스택 Bottom Address 근처에 Push하거든요. 이번에는 Exception(Data abort)이 발생했을 때 스택에 어떤 값들을 Push하는 지 점검해 볼께요.
아래는 ch_pop_remote_rx_intent() 함수에서 exception이 발생한 콜스택인데요. Trace32로 잡았어요. 이 때 Stack 정보 좀 살펴볼께요.
-000|do_mem_abort()
-001|el1_da(asm)
-->|exception
-002|ch_pop_remote_rx_intent()
-003|glink_tx_common()
-004|glink_txv()
-005|ipc_router_glink_xprt_write()
-006|msm_ipc_router_write_pkt(inline)
-006|msm_ipc_router_send_to()
-007|msm_ipc_router_sendmsg()
-008|sock_sendmsg_nosec(inline)
-008|sock_sendmsg()
-009|SYSC_sendto(inline)
-009|sys_sendto()
-010|el0_svc_naked(asm)
.
[1]: data abort에 실행되는 el1_da exception vector 심볼이 보이네요.
[2]: Exception이 발생하는 순간, ARM Processor는 x0부터 PC(Program Counter)까지 레지스터를 스택에 바로 Push해요
[3]: FFFFFFE4DE6A79C8 메모리 주소에 스택 주소가 저장되어 있는데 스택 주소를 보여주고 있어요.
_____________address|_data____________________|value_________________|symbol
NSD:FFFFFFE4DE6A77C0| 50 71 84 9A 9F FF FF FF 0xFFFFFF9F9A847150 \\vmlinux\fault\fault_info+0xA8
NSD:FFFFFFE4DE6A77C8| 25 00 00 00 00 00 00 00 0x25
NSD:FFFFFFE4DE6A77D0| 01 00 00 00 00 00 00 00 0x1
NSD:FFFFFFE4DE6A77D8| 48 7B 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7B48
NSD:FFFFFFE4DE6A77E0| 00 00 00 00 00 00 00 00 0x0
NSD:FFFFFFE4DE6A77E8| 00 40 6A DE E4 FF FF FF 0xFFFFFFE4DE6A4000
NSD:FFFFFFE4DE6A77F0| 00 F0 8C AF 7B 00 00 00 0x7BAF8CF000
NSD:FFFFFFE4DE6A77F8| E0 EB 0C 59 E5 FF FF FF 0xFFFFFFE5590CEBE0
NSD:FFFFFFE4DE6A7800| 00 7A 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7A00
NSD:FFFFFFE4DE6A7808| FC 26 68 99 9F FF FF FF 0xFFFFFF9F996826FC \\vmlinux\Global\el1_da+0x24 //<<-- [1]
NSD:FFFFFFE4DE6A7810| 68 D3 5E 77 E5 FF FF FF 0xFFFFFFE5775ED368
NSD:FFFFFFE4DE6A7818| 00 00 00 00 80 00 00 00 0x8000000000
NSD:FFFFFFE4DE6A7820| 00 30 BA 82 00 00 00 00 0x82BA3000
NSD:FFFFFFE4DE6A7828| 50 E4 B0 99 9F FF FF FF 0xFFFFFF9F99B0E450 \\vmlinux\glink\ch_pop_remote_rx_intent+0xF4
NSD:FFFFFFE4DE6A7830| C5 01 40 80 00 00 00 00 0x804001C5
NSD:FFFFFFE4DE6A7838| 70 F9 13 71 E5 FF FF FF 0xFFFFFFE57113F970
NSD:FFFFFFE4DE6A7840| 00 00 00 00 00 00 00 00 0x0
NSD:FFFFFFE4DE6A7848| 00 00 00 00 00 00 00 00 0x0
NSD:FFFFFFE4DE6A7850| 88 43 F2 F1 E4 FF FF FF 0xFFFFFFE4F1F24388
NSD:FFFFFFE4DE6A7858| 00 60 AF 9B 9F FF FF FF 0xFFFFFF9F9BAF6000 \\vmlinux\Global\nf_conntrack_locks+0xA00
NSD:FFFFFFE4DE6A7860| 01 00 00 00 00 00 00 00 0x1
NSD:FFFFFFE4DE6A7868| 06 00 00 00 00 00 00 00 0x6
NSD:FFFFFFE4DE6A7870| 80 7A 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7A80
NSD:FFFFFFE4DE6A7878| B0 6C AF 9B 9F FF FF FF 0xFFFFFF9F9BAF6CB0 \\vmlinux\Global\cpusets_enabled_key
NSD:FFFFFFE4DE6A7880| 00 70 AF 9B 9F FF FF FF 0xFFFFFF9F9BAF7000 \\vmlinux\trace/ftrace\ftrace_func_hash+0x278
NSD:FFFFFFE4DE6A7888| 00 00 16 71 E5 FF FF FF 0xFFFFFFE571160000
NSD:FFFFFFE4DE6A7890| A0 78 6A DE E4 FF FF FF 0xFFFFFFE4DE6A78A0
NSD:FFFFFFE4DE6A7898| 00 C3 D5 9B 9F FF FF FF 0xFFFFFF9F9BD5C300 \\vmlinux\Global\contig_page_data+0x1800
NSD:FFFFFFE4DE6A78A0| 50 79 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7950
NSD:FFFFFFE4DE6A78A8| 20 09 92 99 9F FF FF FF 0xFFFFFF9F99920920 \\vmlinux\services\security_compute_av+0x128
NSD:FFFFFFE4DE6A78B0| E0 78 6A DE E4 FF FF FF 0xFFFFFFE4DE6A78E0
NSD:FFFFFFE4DE6A78B8| DC CC 79 99 9F FF FF FF 0xFFFFFF9F9979CCDC \\vmlinux\swap\lru_cache_add_active_or_unevictable+0x4C
NSD:FFFFFFE4DE6A78C0| C0 96 44 55 BE FF FF FF 0xFFFFFFBE554496C0
NSD:FFFFFFE4DE6A78C8| 3C 6B 77 2B 46 76 A8 C2 0xC2A876462B776B3C
NSD:FFFFFFE4DE6A78D0| 00 B6 19 E8 E4 FF FF FF 0xFFFFFFE4E819B600 // x0 //<<-- [2]
NSD:FFFFFFE4DE6A78D8| 40 01 00 00 00 00 00 00 0x140 // x1
NSD:FFFFFFE4DE6A78E0| 00 00 20 13 80 FF FF FF 0xFFFFFF8013200000 // x2
NSD:FFFFFFE4DE6A78E8| 00 02 00 00 00 00 00 00 0x200 // x3
NSD:FFFFFFE4DE6A78F0| 28 7B 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7B28 // x4
NSD:FFFFFFE4DE6A78F8| B0 FF 1F 13 80 FF FF FF 0xFFFFFF80131FFFB0 // x5
NSD:FFFFFFE4DE6A7900| 10 00 20 13 80 FF FF FF 0xFFFFFF8013200010 // x6
NSD:FFFFFFE4DE6A7908| 00 00 00 00 00 00 00 00 0x0 // x7
NSD:FFFFFFE4DE6A7910| 00 07 C6 4F E5 FF FF FF 0xFFFFFFE54FC60700 // x8
NSD:FFFFFFE4DE6A7918| 00 00 00 00 00 00 00 00 0x0 // x9
NSD:FFFFFFE4DE6A7920| 00 00 00 00 00 00 00 00 0x0 // x10
NSD:FFFFFFE4DE6A7928| 00 00 00 00 00 00 00 00 0x0 // x11
NSD:FFFFFFE4DE6A7930| 00 00 00 00 00 00 00 00 0x0 // x12
NSD:FFFFFFE4DE6A7938| 00 00 00 00 00 00 00 00 0x0 // x13
NSD:FFFFFFE4DE6A7940| 00 00 00 00 00 00 00 00 0x0 // x14
NSD:FFFFFFE4DE6A7948| AB AA AA AA AA AA AA AA 0xAAAAAAAAAAAAAAAB // x15
NSD:FFFFFFE4DE6A7950| 04 BA 5E 9A 9F FF FF FF 0xFFFFFF9F9A5EBA04 \\vmlinux\socket\sys_sendto // x16
NSD:FFFFFFE4DE6A7958| 14 B3 AB B2 7B 00 00 00 0x7BB2ABB314 // x17
NSD:FFFFFFE4DE6A7960| D6 00 00 00 00 00 00 00 0xD6 // x18
NSD:FFFFFFE4DE6A7968| 68 D3 5E 77 E5 FF FF FF 0xFFFFFFE5775ED368 // x19
NSD:FFFFFFE4DE6A7970| 28 00 00 00 00 00 00 00 0x28 // x20
NSD:FFFFFFE4DE6A7978| 60 D3 5E 77 E5 FF FF FF 0xFFFFFFE5775ED360 // x21
NSD:FFFFFFE4DE6A7980| 28 7B 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7B28 // x22
NSD:FFFFFFE4DE6A7988| 20 7B 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7B20 // x23
NSD:FFFFFFE4DE6A7990| 1C 7B 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7B1C // x24
NSD:FFFFFFE4DE6A7998| 01 00 00 00 00 00 00 00 0x1 // x25
NSD:FFFFFFE4DE6A79A0| 48 7B 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7B48 // x26
NSD:FFFFFFE4DE6A79A8| 00 00 00 00 00 00 00 00 0x0 // x27
NSD:FFFFFFE4DE6A79B0| 00 D2 5E 77 E5 FF FF FF 0xFFFFFFE5775ED200 // x28
NSD:FFFFFFE4DE6A79B8| 00 7A 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7A00 // x29
NSD:FFFFFFE4DE6A79C0| 08 E4 B0 99 9F FF FF FF 0xFFFFFF9F99B0E408 \\vmlinux\glink\ch_pop_remote_rx_intent+0xAC // x30
NSD:FFFFFFE4DE6A79C8| 00 7A 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7A00 // SP
NSD:FFFFFFE4DE6A79D0| 50 E4 B0 99 9F FF FF FF 0xFFFFFF9F99B0E450 \\vmlinux\glink\ch_pop_remote_rx_intent+0xF4 // PC
NSD:FFFFFFE4DE6A79D8| C5 01 40 80 00 00 00 00 0x804001C5 // CPSR
NSD:FFFFFFE4DE6A79E0| 00 7A 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7A00
NSD:FFFFFFE4DE6A79E8| 08 E4 B0 99 9F FF FF FF 0xFFFFFF9F99B0E408 \\vmlinux\glink\ch_pop_remote_rx_intent+0xAC
NSD:FFFFFFE4DE6A79F0| 00 00 00 00 80 00 00 00 0x8000000000
NSD:FFFFFFE4DE6A79F8| 0C D2 5E 77 E5 FF FF FF 0xFFFFFFE5775ED20C
NSD:FFFFFFE4DE6A7A00| 60 7A 6A DE E4 FF FF FF 0xFFFFFFE4DE6A7A60 //<<-- [3]
NSD:FFFFFFE4DE6A7A08| 0C 15 B1 99 9F FF FF FF 0xFFFFFF9F99B1150C \\vmlinux\glink\glink_tx_common+0x228
NSD:FFFFFFE4DE6A7A10| 00 06 C6 4F E5 FF FF FF 0xFFFFFFE54FC60600
NSD:FFFFFFE4DE6A7A18| 0C D2 5E 77 E5 FF FF FF 0xFFFFFFE5775ED20C
이렇게 스택에 Push된 레지스터를 확인하는 이유는 Exception으로 발생한 커널 패닉이 왜 발생했는지 정확히 점검할 수 있기 때문이에요.
그리고 가끔 Stack Corruption으로 커널 패닉이 발생하는 경우도 있거든요. 이럴 때 스택에 있는 값들을 하나 하나 씩 점검해서 어떻게 Stack이 Push되었는지 점검할 필요가 있어요.
최근 덧글