do_undefinstr问题分析思路

文章详细展示了如何对Linux内核的log进行分析,以定位和理解系统出现的bug,特别是针对undefinedinstruction的问题。通过crash工具和fulldump信息,追踪异常的调用栈,检查内存中的指令与vmlinux代码段的匹配性,从而判断是否存在CPU取指错误或内存损坏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 log分析

首先肯定要解析db,获取到最后的kernel log打印,如下:

<4>[565841.738606]-(6)[31160:sAsync#14]------------[ cut here ]------------
<2>[565841.738617]-(6)[31160:sAsync#14]Kernel BUG at do_undefinstr+0x488/0x48c [verbose debug info unavailable]
<0>[565841.738620]-(6)[31160:sAsync#14]Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
<4>[565841.738842]-(5)[31089:com.talpa.share]------------[ cut here ]------------
<2>[565841.738849]-(5)[31089:com.talpa.share]Kernel BUG at do_undefinstr+0x488/0x48c [verbose debug info unavailable]
<5>[565841.743643]-(6)[31160:sAsync#14]Kernel Offset: 0x2966400000 from 0xffffff8008000000
<5>[565841.743645]-(6)[31160:sAsync#14]PHYS_OFFSET: 0xffffffdc80000000
<4>[565841.743647]-(6)[31160:sAsync#14]Modules linked in: wlan_drv_gen4m ffffffa925223000 ffffffa925470000 2408448 266240 (O) wmt_chrdev_wifi ffffffa925212000 ffffffa92521c000 36864 24576 (O) gps_drv ffffffa925193000 ffffffa925116000 516096 45056 (O) fmradio_drv_connac2x ffffffa925163000 ffffffa9250b2000 192512 28672 (O) bt_drv_6893 ffffffa9250db000 ffffffa925116000 237568 53248 (O) tran_fre ffffffa9250c6000 ffffffa9250d4000 53248 24576 (PO) dev_gc ffffffa9250bd000 ffffffa9250c3000 20480 8192 (O) conninfra ffffffa925065000 ffffffa9250a4000 253952 65536 (O) connfem ffffffa925055000 ffffffa925060000 40960 16384 (O) app_defrag ffffffa925046000 ffffffa925051000 40960 12288 (O) fpsgo ffffffa924f28000 ffffffa925042000 1150976 12288 (PO) tran_gc_ko ffffffa924ede000 ffffffa924eea000 45056 16384 (O) trace_mmstat ffffffa924ed4000 ffffffa924eda000 20480 12288 
<5>[565841.744500]-(6)[31160:sAsync#14]mrdump: add CCCI:0xffffffe58ce70000 sz:0x0 failed
<4>[565841.744504]-(6)[31160:sAsync#14]CPU: 6 PID: 31160 Comm: sAsync#14 Tainted: P S      W  O      4.19.191+ #1
<4>[565841.744506]-(6)[31160:sAsync#14]Hardware name: MT6893Z/CZA (DT)
<4>[565841.744508]-(6)[31160:sAsync#14]pstate: 00400005 (nzcv daif +PAN -UAO)
<4>[565841.744510]-(6)[31160:sAsync#14]pc : do_undefinstr+0x488/0x48c
<4>[565841.744512]-(6)[31160:sAsync#14]lr : do_undefinstr+0x440/0x48c
<4>[565841.744514]-(6)[31160:sAsync#14]sp : ffffff8026d2b5c0
<4>[565841.744515]-(6)[31160:sAsync#14]x29: ffffff8026d2b5d0 x28: ffffffe4da52ec40 
<4>[565841.744517]-(6)[31160:sAsync#14]x27: ffffffe586cec11c x26: ffffffbf9459b088 
<4>[565841.744519]-(6)[31160:sAsync#14]x25: ffffffe584e76034 x24: 0000000000000000 
<4>[565841.744521]-(6)[31160:sAsync#14]x23: 0000000020400005 x22: ffffffa96e525308 
<4>[565841.744522]-(6)[31160:sAsync#14]x21: 0000000000000000 x20: 0000000091ff042f 
<4>[565841.744524]-(6)[31160:sAsync#14]x19: ffffff8026d2b610 x18: 0000000000000003 
<4>[565841.744526]-(6)[31160:sAsync#14]x17: ffffffe53524ef7e x16: ffffffe53524eed7 
<4>[565841.744527]-(6)[31160:sAsync#14]x15: 0000000000000000 x14: ffffffe3ef8e84b8 
<4>[565841.744529]-(6)[31160:sAsync#14]x13: 0000000000000104 x12: 000000002e905f6c 
<4>[565841.744531]-(6)[31160:sAsync#14]x11: 0000000000000bbc x10: 0000000000000001 
<4>[565841.744533]-(6)[31160:sAsync#14]x9 : 5c1a7733f46e8800 x8 : 0000000000000005 
<4>[565841.744534]-(6)[31160:sAsync#14]x7 : 0000000000000000 x6 : ffffff8026d2b5c8 
<4>[565841.744536]-(6)[31160:sAsync#14]x5 : 0000000000000000 x4 : 0000000000000001 
<4>[565841.744538]-(6)[31160:sAsync#14]x3 : 0000000000000001 x2 : 0000000000000080 
<4>[565841.744539]-(6)[31160:sAsync#14]x1 : 0000000000000000 x0 : 0000000000000000 
<4>[565841.744542]-(6)[31160:sAsync#14]CPU: 6 PID: 31160 Comm: sAsync#14 Tainted: P S      W  O      4.19.191+ #1
<4>[565841.744543]-(6)[31160:sAsync#14]Hardware name: MT6893Z/CZA (DT)
<4>[565841.744545]-(6)[31160:sAsync#14]Call trace:
<4>[565841.744548]-(6)[31160:sAsync#14] dump_backtrace+0x0/0x158
<4>[565841.744550]-(6)[31160:sAsync#14] show_stack+0x14/0x1c
<4>[565841.744554]-(6)[31160:sAsync#14] dump_stack+0xb8/0xf0
<4>[565841.744557]-(6)[31160:sAsync#14] mrdump_common_die+0x170/0x214
<4>[565841.744559]-(6)[31160:sAsync#14] ipanic_die+0x30/0x40
<4>[565841.744562]-(6)[31160:sAsync#14] notify_die+0x64/0xb4
<4>[565841.744564]-(6)[31160:sAsync#14] die+0xac/0x37c
<4>[565841.744566]-(6)[31160:sAsync#14] bug_handler+0x4c/0x84
<4>[565841.744568]-(6)[31160:sAsync#14] brk_handler+0x9c/0x168
<4>[565841.744569]-(6)[31160:sAsync#14] do_debug_exception+0xe4/0x180
<4>[565841.744571]-(6)[31160:sAsync#14] el1_dbg+0x18/0xa8
<4>[565841.744573]-(6)[31160:sAsync#14] do_undefinstr+0x488/0x48c
<4>[565841.744574]-(6)[31160:sAsync#14] el1_undef+0x10/0xa0
<4>[565841.744577]-(6)[31160:sAsync#14] down_read_trylock+0x14/0x54
<4>[565841.744579]-(6)[31160:sAsync#14] scsi_dispatch_cmd+0x144/0x21c
<4>[565841.744582]-(6)[31160:sAsync#14] scsi_request_fn+0x3f4/0x604
<4>[565841.744584]-(6)[31160:sAsync#14] __blk_run_queue+0x48/0x80
<4>[565841.744586]-(6)[31160:sAsync#14] cfq_insert_request+0x4a4/0x5bc
<4>[565841.744588]-(6)[31160:sAsync#14] __elv_add_request+0x348/0x3cc
<4>[565841.744590]-(6)[31160:sAsync#14] blk_flush_plug_list+0x1dc/0x24c
<4>[565841.744593]-(6)[31160:sAsync#14] blk_finish_plug+0x24/0x34
<4>[565841.744595]-(6)[31160:sAsync#14] read_pages+0x74/0x148
<4>[565841.744597]-(6)[31160:sAsync#14] __do_page_cache_readahead+0x164/0x1c4
<4>[565841.744600]-(6)[31160:sAsync#14] filemap_fault+0x2f0/0x694
<4>[565841.744602]-(6)[31160:sAsync#14] __do_fault+0x7c/0xe8
<4>[565841.744605]-(6)[31160:sAsync#14] handle_pte_fault+0xa00/0xdb0
<4>[565841.744606]-(6)[31160:sAsync#14] __handle_speculative_fault+0x228/0x368
<4>[565841.744608]-(6)[31160:sAsync#14] do_page_fault+0x258/0x554
<4>[565841.744610]-(6)[31160:sAsync#14] do_translation_fault+0x2c/0x40
<4>[565841.744612]-(6)[31160:sAsync#14] do_mem_abort+0x4c/0xf8
<4>[565841.744613]-(6)[31160:sAsync#14] el0_da+0x1c/0x20

二 crash分析

主要利用到crash + fulldump信息,去追踪溯源,详细flow如下:

crash-new> bt
PID: 31089  TASK: ffffffe452dc49c0  CPU: 5   COMMAND: "com.talpa.share"
 #0 [ffffff80256f3790] queued_spin_lock_slowpath at ffffffa96e525bcc
 #1 [ffffff80256f3800] die at ffffffa96e4922d0
 #2 [ffffff80256f3860] bug_handler at ffffffa96e492fd0
 #3 [ffffff80256f3910] brk_handler at ffffffa96e487130
 #4 [ffffff80256f39d0] do_debug_exception at ffffffa96e481128
 #5 [ffffff80256f3b40] el1_dbg at ffffffa96e482d20
     PC: ffffffa96e480c88  [do_undefinstr+1160]
     LR: ffffffa96e480c40  [do_undefinstr+1088]
     SP: ffffff80256f3b50  PSTATE: 00400005
    X29: ffffff80256f3b60  X28: ffffffe452dc49c0  X27: 0000000000000000
    X26: ffffffe496a52968  X25: 0000000000000002  X24: 0000000000000000
    X23: 0000000060400005  X22: ffffffa96e525308  X21: 0000000000000000
    X20: 0000000091ff042f  X19: ffffff80256f3ba0  X18: 0000000000000000
    X17: 0000000000000000  X16: 0000000000000000  X15: 0000000000000000
    X14: 0000000000000000  X13: 0000000000000104  X12: 000000006184d817
    X11: 0000000000000938  X10: 0000000000000001   X9: 5c1a7733f46e8800
     X8: 0000000000000005   X7: 0000000000000000   X6: ffffff80256f3b58
     X5: 0000000000000000   X4: 0000000000000001   X3: 0000000000000001
     X2: 0000000000000080   X1: 0000000000000000   X0: 0000000000000000
 #6 [ffffff80256f3b60] do_undefinstr at ffffffa96e480c84
 #7 [ffffff80256f3cd0] el1_undef at ffffffa96e482c78
     PC: ffffffa96e525308  [down_read_trylock+20] =>pc的位置:ffffffa96e525308
     LR: ffffffa96f4f7464  [do_page_fault+620]
     SP: ffffff80256f3ce0  PSTATE: 60400005
    X29: ffffff80256f3d80  X28: ffffffe452dc49c0  X27: 0000000000000000
    X26: ffffffe496a52968  X25: 0000000000000002  X24: 0000000000000055
    X23: ffffffe496a52900  X22: ffffff80256f3ec0  X21: ffffffe452dc49c0
    X20: 00000074b9c59000  X19: 0000000092000047  X18: 0000000000000000
    X17: 0000000000000000  X16: 0000000000000000  X15: 0000000000000000
    X14: 0000000000000000  X13: 0000000000000000  X12: 0000000000000002
    X11: 00000000fffff000  X10: 0000000000000000   X9: 5c1a7733f46e8800
     X8: ffffffe496a52968   X7: 0000000000000000   X6: 0000000000000000
     X5: 0000000000000000   X4: 0000000000000000   X3: 0000000000000002
     X2: ffffffffffffffff   X1: 0000000000000000   X0: ffffffe496a52968
 #8 [ffffff80256f3d80] down_read_trylock at ffffffa96e525304

kernel offset = 0x2966400000
=》对应在vmlinux的代码段的地址:
ffffffa96e525308 - 0x2966400000 = FFFFFF8008125308

junfang1@buildsrv-n43:~/work/gdb-crash-tool/CK9N$ llvm-objdump -t vmlinux | grep down_read_trylock
ffffff800969aceb l     O __ksymtab_strings      0000000000000012 __kstrtab_down_read_trylock
ffffff8009677ab8 l       __ksymtab      0000000000000000 __ksymtab_down_read_trylock
ffffff80081252f4 g     F .text  0000000000000054 down_read_trylock =》here
00000000384549cc g       ABS  0000000000000000 __crc_down_read_trylock
ffffff8008592fd0 g     F .text  0000000000000048 ldsem_down_read_trylock

此部分是通过objdump vmlinux得出的:
174936 ffffff80081252f4 <down_read_trylock>:
  174937 ffffff80081252f4: fe 0f 1f f8   str x30, [sp, #-16]!
  174938 ffffff80081252f8: e8 03 00 aa   mov x8, x0
  174939 ffffff80081252fc: 01 01 40 f9   ldr x1, [x8]
  174940 ffffff8008125300: e1 01 f8 b7   tbnz  x1, #63, 0xffffff800812533c <down_read_trylock+0x48>
  174941 ffffff8008125304: e0 03 08 aa   mov x0, x8
  174942 ffffff8008125308: 22 04 00 91   add x2, x1, #1 =》here,对应的指令为:91000422
  174943 ffffff800812530c: b3 d9 0e 94   bl  0xffffff80084db9d8 <__ll_sc___cmpxchg_case_acq_8>
  174944 ffffff8008125310: 1f 20 03 d5   nop
  174945 ffffff8008125314: 1f 20 03 d5   nop
  174946 ffffff8008125318: 3f 00 00 eb   cmp x1, x0
  174947 ffffff800812531c: 01 ff ff 54   b.ne  0xffffff80081252fc <down_read_trylock+0x8>
  174948 ffffff8008125320: 09 11 40 f9   ldr x9, [x8, #32]
  174949 ffffff8008125324: 20 00 80 52   mov w0, #1
  174950 ffffff8008125328: 3f 05 00 f1   cmp x9, #1
  174951 ffffff800812532c: 40 00 00 54   b.eq  0xffffff8008125334 <down_read_trylock+0x40>
  174952 ffffff8008125330: 00 11 00 f9   str x0, [x8, #32]
  174953 ffffff8008125334: fe 07 41 f8   ldr x30, [sp], #16
  174954 ffffff8008125338: c0 03 5f d6   ret
  174955 ffffff800812533c: e0 03 1f 2a   mov w0, wzr
  174956 ffffff8008125340: fe 07 41 f8   ldr x30, [sp], #16

dump对应的内存数据:(备注:如果没有fulldump的,可以用gdb的minidump去读取相关内存情况:x xx这种,但是不一定能读出来,还是依赖fulldump)
crash-new> rd ffffffa96e525308 10
ffffffa96e525308:  aa0103fe91000422 aa1e03e0c8fe7d02   "........}......
ffffffa96e525318:  54ffff01eb00003f 52800020f9401109   ?......T..@. ..R
ffffffa96e525328:  54000040f100053f f84107fef9001100   ?...@..T......A.
ffffffa96e525338:  2a1f03e0d65f03c0 d65f03c0f84107fe   .._....*..A..._.
ffffffa96e525348:  aa0003e8f81f0ffe b26083e2aa1f03e1   ..............`.

dump出来的指令与vmlinux代码段的指令是匹配的,所以DRAM本身没有发生bitflip,但是可能cpu在取指令过程中发生了bitflip,cpu异常

junfang1@buildsrv-n43:~/work/gdb-crash-tool/CK9N$ llvm-objdump -d vmlinux --start-address=0xffffff80081252f4 --stop-address=0xffffff8008125344

vmlinux:        file format elf64-littleaarch64


Disassembly of section .text:

ffffff80081252f4 <down_read_trylock>:
ffffff80081252f4: fe 0f 1f f8   str     x30, [sp, #-16]!
ffffff80081252f8: e8 03 00 aa   mov     x8, x0
ffffff80081252fc: 01 01 40 f9   ldr     x1, [x8]
ffffff8008125300: e1 01 f8 b7   tbnz    x1, #63, 0xffffff800812533c <down_read_trylock+0x48>
ffffff8008125304: e0 03 08 aa   mov     x0, x8
ffffff8008125308: 22 04 00 91   add     x2, x1, #1
ffffff800812530c: b3 d9 0e 94   bl      0xffffff80084db9d8 <__ll_sc___cmpxchg_case_acq_8>
ffffff8008125310: 1f 20 03 d5   nop
ffffff8008125314: 1f 20 03 d5   nop
ffffff8008125318: 3f 00 00 eb   cmp     x1, x0
ffffff800812531c: 01 ff ff 54   b.ne    0xffffff80081252fc <down_read_trylock+0x8>
ffffff8008125320: 09 11 40 f9   ldr     x9, [x8, #32]
ffffff8008125324: 20 00 80 52   mov     w0, #1
ffffff8008125328: 3f 05 00 f1   cmp     x9, #1
ffffff800812532c: 40 00 00 54   b.eq    0xffffff8008125334 <down_read_trylock+0x40>
ffffff8008125330: 00 11 00 f9   str     x0, [x8, #32]
ffffff8008125334: fe 07 41 f8   ldr     x30, [sp], #16
ffffff8008125338: c0 03 5f d6   ret
ffffff800812533c: e0 03 1f 2a   mov     w0, wzr
ffffff8008125340: fe 07 41 f8   ldr     x30, [sp], #16

三 归纳

此类方法通用就是看实际中dump出来的指令与vmlinux中的指令是否匹配,所以通用的流程如下几步,可以套用所有

第一步:加载coredump,找到未定义指令的pc位置
crash-8-0> bt
PID: 0      TASK: fffffff68eeec9c0  CPU: 1   COMMAND: "swapper/1"
 #0 [ffffff8008153cf0] do_undefinstr at ffffff990ac80c84
 #1 [ffffff8008153e60] el1_undef at ffffff990ac82c78
     PC: ffffff990ad63dc4  [__tick_broadcast_oneshot_control+272] =》先确认pc的位置,执行到此处出现了未定义指令
     LR: ffffff990ad63d04  [__tick_broadcast_oneshot_control+80]
     SP: ffffff8008153e70  PSTATE: 40c00085
    X29: ffffff8008153e80  X28: ffffff990c64c000  X27: fffffff6662c7b28
    X26: fffffff68eeec9c0  X25: 0000000000000001  X24: 0000000000000001
    X23: 0000000000000000  X22: 0000000000000000  X21: 0000000000000002
    X20: fffffff6bfcec200  X19: 000164b8b30aaf45  X18: 0000000000000746
    X17: 071c71c71c71c71c  X16: 0000000000000002  X15: 000000000000107d
    X14: 0000000000000991  X13: 00000000000000b6  X12: 0000000266a1d25c
    X11: 0000000000000015  X10: 00000000099d89d9   X9: 0000000000000001
     X8: 00000000000000f2   X7: 0000000000000000   X6: 0000000000000000
     X5: 0000000000000000   X4: 0000000000000001   X3: 0000000000000001
     X2: 0000000000000001   X1: ffffff990c884048   X0: 0000000000000000
 #2 [ffffff8008153e80] __tick_broadcast_oneshot_control at ffffff990ad63dc0
 #3 [ffffff8008153ed0] tick_broadcast_oneshot_control at ffffff990ad62b40
 #4 [ffffff8008153ee0] cpuidle_enter_state at ffffff990b8a9960
 #5 [ffffff8008153f40] cpuidle_enter at ffffff990b8a9a48
 #6 [ffffff8008153f60] do_idle at ffffff990acf98cc
 #7 [ffffff8008153fc0] cpu_startup_entry at ffffff990acf99c4
 #8 [ffffff8008153fe0] secondary_start_kernel at ffffff990ac9996c

所以未定义的代码:pc = ffffff990ad63dc4

第二步:找到kernel offset,计算出在vmlinux里面的code偏移

pc - 0x1902c00000 = ffffff990ad63dc4 - 0x1902c00000 = ffffff8008163dc4

第三步:反汇编vmlinux
junfang1@buildsrv-n43:~/work/gdb-crash-tool/x6710/TLMPYAEE-446$ llvm-objdump -D vmlinux > vmlinux.dis

第四步:根据前面计算的pc位置找到vmlinux对应的执行指令:

vim vmlinux.dis => 定位到 ffffff8008163dc4这一行

  242251 ffffff8008163d94: 08 d9 00 b0   adrp  x8, 0xffffff8009c84000 <$x.242>
  242252 ffffff8008163d98: b6 7e 46 d3   ubfx  x22, x21, #6, #26
  242253 ffffff8008163d9c: 08 21 01 91   add x8, x8, #72
  242254 ffffff8008163da0: 01 4d 36 8b   add x1, x8, w22, uxtw #3
  242255 ffffff8008163da4: 28 00 40 f9   ldr x8, [x1]
  242256 ffffff8008163da8: 29 00 80 52   mov w9, #1
  242257 ffffff8008163dac: 35 21 d5 9a   lsl x21, x9, x21
  242258 ffffff8008163db0: e8 07 00 f9   str x8, [sp, #8]
  242259 ffffff8008163db4: e8 07 40 f9   ldr x8, [sp, #8]
  242260 ffffff8008163db8: 1f 01 15 ea   tst x8, x21
  242261 ffffff8008163dbc: 40 0d 00 54   b.eq  0xffffff8008163f64 <__tick_broadcast_oneshot_cont         rol+0x2b0>
  242262 ffffff8008163dc0: e0 03 15 aa   mov x0, x21
  242263 ffffff8008163dc4: a8 de 0d 94   bl  0xffffff80084db864 <__ll_sc_atomic64_fetch_andnot> =>here,所以对应执行的机器指令就是:a8 de 0d 94
  242264 ffffff8008163dc8: 1f 00 15 ea   tst x0, x21
  242265 ffffff8008163dcc: c0 0c 00 54   b.eq  0xffffff8008163f64 <__tick_broadcast_oneshot_cont         rol+0x2b0>

第五步:直接读取内存中dump的数据

crash-8-0> rd ffffff990ad63dc4 10
ffffff990ad63dc4:  ea15001ff8e01020 5280006154000cc0    ..........Ta..R
ffffff990ad63dd4:  97fff5b0aa1403e0 91014108b000d908   .............A..
ffffff990ad63de4:  f94000288b160d01 f94007e8f90007e8   ....(.@.......@.
ffffff990ad63df4:  540000a0ea15011f f8e01020aa1503e0   .......T.... ...
ffffff990ad63e04:  54000ae1ea15001f 92f00009f9400e88   .......T..@.....

读出来的机器指令是:f8e01020 ,实际vmlinux的指令是:940ddea8 

看起来和vmlinux中的指令不一样指令可能被破坏了,内存中dump的指令已经存在异常了,不排除被踩坏或者memory异常

进一步对比:
vmlinux里面的这段代码:
  242251 ffffff8008163d94: 08 d9 00 b0   adrp  x8, 0xffffff8009c84000 <$x.242>
  242252 ffffff8008163d98: b6 7e 46 d3   ubfx  x22, x21, #6, #26
  242253 ffffff8008163d9c: 08 21 01 91   add x8, x8, #72
  242254 ffffff8008163da0: 01 4d 36 8b   add x1, x8, w22, uxtw #3
  242255 ffffff8008163da4: 28 00 40 f9   ldr x8, [x1]
  242256 ffffff8008163da8: 29 00 80 52   mov w9, #1
  242257 ffffff8008163dac: 35 21 d5 9a   lsl x21, x9, x21
  242258 ffffff8008163db0: e8 07 00 f9   str x8, [sp, #8]
  242259 ffffff8008163db4: e8 07 40 f9   ldr x8, [sp, #8]
  242260 ffffff8008163db8: 1f 01 15 ea   tst x8, x21
  242261 ffffff8008163dbc: 40 0d 00 54   b.eq  0xffffff8008163f64 <__tick_broadcast_oneshot_cont         rol+0x2b0>
  242262 ffffff8008163dc0: e0 03 15 aa   mov x0, x21
  242263 ffffff8008163dc4: a8 de 0d 94   bl  0xffffff80084db864 <__ll_sc_atomic64_fetch_andnot>
  242264 ffffff8008163dc8: 1f 00 15 ea   tst x0, x21
  242265 ffffff8008163dcc: c0 0c 00 54   b.eq  0xffffff8008163f64 <__tick_broadcast_oneshot_cont         rol+0x2b0>

crash里面dump出来的这段代码:
crash-8-0> dis __tick_broadcast_oneshot_control
0xffffff990ad63cb4 <__tick_broadcast_oneshot_control>:  sub     sp, sp, #0x60
0xffffff990ad63cb8 <__tick_broadcast_oneshot_control+4>:        stp     x29, x30, [sp, #16]
0xffffff990ad63cbc <__tick_broadcast_oneshot_control+8>:        stp     x26, x25, [sp, #32]
0xffffff990ad63cc0 <__tick_broadcast_oneshot_control+12>:       stp     x24, x23, [sp, #48]
0xffffff990ad63cc4 <__tick_broadcast_oneshot_control+16>:       stp     x22, x21, [sp, #64]
0xffffff990ad63cc8 <__tick_broadcast_oneshot_control+20>:       stp     x20, x19, [sp, #80]
0xffffff990ad63ccc <__tick_broadcast_oneshot_control+24>:       add     x29, sp, #0x10
................
0xffffff990ad63d90 <__tick_broadcast_oneshot_control+220>:      b       0xffffff990ad64050 <__tick_broadcast_oneshot_control+924>
0xffffff990ad63d94 <__tick_broadcast_oneshot_control+224>:      adrp    x8, 0xffffff990c884000 <tick_broadcast_mtk_aee_dump_buf+63>
0xffffff990ad63d98 <__tick_broadcast_oneshot_control+228>:      ubfx    x22, x21, #6, #26
0xffffff990ad63d9c <__tick_broadcast_oneshot_control+232>:      add     x8, x8, #0x48
0xffffff990ad63da0 <__tick_broadcast_oneshot_control+236>:      add     x1, x8, w22, uxtw #3
0xffffff990ad63da4 <__tick_broadcast_oneshot_control+240>:      ldr     x8, [x1]
0xffffff990ad63da8 <__tick_broadcast_oneshot_control+244>:      mov     w9, #0x1                        // #1
0xffffff990ad63dac <__tick_broadcast_oneshot_control+248>:      lsl     x21, x9, x21
0xffffff990ad63db0 <__tick_broadcast_oneshot_control+252>:      str     x8, [sp, #8]
0xffffff990ad63db4 <__tick_broadcast_oneshot_control+256>:      ldr     x8, [sp, #8]
0xffffff990ad63db8 <__tick_broadcast_oneshot_control+260>:      tst     x8, x21
0xffffff990ad63dbc <__tick_broadcast_oneshot_control+264>:      b.eq    0xffffff990ad63f64 <__tick_broadcast_oneshot_control+688>  // b.none
0xffffff990ad63dc0 <__tick_broadcast_oneshot_control+268>:      mov     x0, x21
0xffffff990ad63dc4 <__tick_broadcast_oneshot_control+272>:      ldclral x0, x0, [x1] =》这条命令
0xffffff990ad63dc8 <__tick_broadcast_oneshot_control+276>:      tst     x0, x21
0xffffff990ad63dcc <__tick_broadcast_oneshot_control+280>:      b.eq    0xffffff990ad63f64 <__tick_broad

附件:

 

<think>好的,我现在需要解决用户关于FPAC致命异常的疑问。首先,我需要理解FPAC是什么。根据提供的引用,特别是引用[2]和[4],FPAC可能与ARM的指针认证(PAC)相关。PAC用于生成和验证指针的加密签名,增强系统安全性,防止代码重用攻击。FEAT_CONSTPACFIELD(引用[4])可能是一种增强PAC的机制,允许使用虚拟地址的特定位决定PAC字段的大小。 接下来,用户提到FPAC致命异常,需要找出其原因和解决方案。根据系统编程的常见问题,PAC相关异常通常与指针签名验证失败有关。例如,当程序尝试使用无效或篡改的指针时,PAC机制会检测到签名不匹配,触发异常。此外,代码中的未定义指令或硬件不支持PAC特性也可能导致问题。 查看引用[3]中的代码片段,do_undefinstr函数处理未定义指令异常,可能会调用相关的钩子函数(call_undef_hook)。如果系统启用了PAC但遇到不支持的操作,可能触发此类异常。此外,如果硬件不支持FEAT_CONSTPACFIELD而软件尝试使用,也可能导致致命异常。 解决方案方面,可能需要检查指针使用是否正确,确保PAC相关的编译选项和硬件支持,调试未定义指令,以及更新工具链和固件。需要将这些点组织成清晰的原因和解决方案,并引用提供的资料支持。 最后,生成相关问题,帮助用户深入理解PAC相关的问题和应用。</think>关于FPAC(Pointer Authentication Code)致命异常的分析与解决方案如下: ### FPAC致命异常的核心原因 1. **指针签名验证失败** 当使用指针认证(PAC)的系统检测到指针的加密签名与预期值不匹配时,会触发FPAC异常。例如: - 指针被恶意篡改(如ROP攻击尝试)[^2] - 内存越界操作意外修改了PAC字段 - 未正确调用PAC指令(如`AUTIA`/`AUTIB`签名验证指令) 2. **硬件/软件兼容性问题** - 系统未启用FEAT_CONSTPACFIELD特性却尝试使用动态PAC字段大小[^4] - 处理器不支持PAC扩展但代码中调用了相关指令(如ARMv8.3之前架构) 3. **未定义指令异常** 在未实现PAC的硬件上执行PAC指令(如`PACIA`),会进入`el1_undef`异常处理流程,最终通过`do_undefinstr`触发致命错误[^3] ### 关键解决方案 1. **代码调试与加固** ```c // 正确使用PAC指令示例(ARMv8.3+) void* sign_pointer(void* ptr) { return __builtin_arm_pacia(ptr, 0); // 使用编译器内置函数生成签名 } ``` - 使用静态分析工具检查指针生命周期 - 在指针传递关键路径(如系统调用)添加PAC验证 2. **系统配置验证** - 通过`ID_AA64ISAR1_EL1`寄存器检查CPU是否支持PAC - 在内核配置中确认`CONFIG_ARM64_PTR_AUTH`已启用 - 对于FEAT_CONSTPACFIELD,需验证虚拟地址位分配是否符合规范 3. **异常处理增强** 参考`do_undefinstr`的处理逻辑: ```c void do_undefinstr(struct pt_regs *regs) { if (is_pac_instruction(regs->insn)) { // 识别PAC指令 handle_pac_fault(regs); // 自定义处理流程 return; } // ...其他未定义指令处理 } ``` 4. **工具链更新** - 使用支持`-msign-return-address`的编译器(如GCC 10+) - 在链接脚本中保留PAC字段所需位宽(通常高位4位)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值