LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

CK:User mode Bus Error(用户空间操作内核地址导致的异常)

关键词:VEC_ACCESS、coredump、LR、PC等。

 

CK中存在一种VEC_ACCESS异常,可能原因是用户空间访问了内核空间,还有一种是内核访问不存在的总线地址。

下面简单构造VEC_ACCESS异常,包括变量指针异常和函数指针异常并分析。

1. 变量指针异常

#include <stdio.h>

void main(void)
{
    char *p = (char *)0xfffffffe;

    *p = 1;
}

执行后异常输出如下,并生成了coredump文件。

[ 1601.325926] User mode Bus Error
[ 1601.329105] 
[ 1601.329105] CURRENT PROCESS:
[ 1601.329105] 
[ 1601.334955] COMM=buserror PID=309
[ 1601.338280] TEXT=00008000-000085c0 DATA=00009f1c-0000a018 BSS=0000a018-0000b000
[ 1601.345596] USER-STACK=7fb0de10  KERNEL-STACK=be829180
[ 1601.345596] 
[ 1601.352229] PC: 0x000084ec (0x84ec)----------------------异常点代码位置。
[ 1601.355724] LR: 0x2aae22aa (0x2aae22aa)
[ 1601.359564] SP: 0xbf0b1f68 
[ 1601.362362] orig_a0: 0x00000001
[ 1601.365506] PSR: 0x00020340                                          
[ 1601.368308]  a0: 0x00000001   a1: 0x7fb0de14   a2: 0x00000001   a3: 0xfffffffe
[ 1601.375539]  r4: 0x00008500   r5: 0x00000000   r6: 0x00000000   r7: 0x00000000
[ 1601.382770]  r8: 0x7fb0dd3c   r9: 0x000c873c  r10: 0x00008380  r11: 0x00000000
[ 1601.390000] r12: 0x001030dc  r13: 0x001030ac  r15: 0x2aae22aa        
[ 1601.395753] r16: 0xffffffff  r17: 0x00000000  r18: 0x2abfa20c  r19: 0x00000000
[ 1601.402984] r20: 0x00000000  r21: 0x00000000  r22: 0x7fb0da10  r23: 0x2aaa8736
[ 1601.410215] r24: 0x2aacdb9c  r25: 0x00000000  r26: 0x00000000  r27: 0x7fb0dd50
[ 1601.417445] r28: 0x2abf7000  r29: 0x00000000  r30: 0x00000000  tls: 0x2aac8a18
[ 1601.424673]  hi: 0x00000000   lo: 0x00000000 
[ 1601.429034] 
CODE:
000084ac: 14904820 e9031066 7bcdfffa 000007f7 
000084bc: 000014d0 00009f2c 00008404 00000000 
000084cc: 00001490 dd0e1421 6e3b2000 e4481421 
000084dc: 33001003 b2602b01 1003e468 32019360 
000084ec: db63a340 6c000000 d90e6fa3 14012000 
000084fc: 0000783c 0116ebe0 0012ea8d 0002cf8c 
0000850c: 003cc5bc d07c1070 6dc30823 6e4b6e07 
0000851c: 7bcd10ae 614e106e c78355a2 e9050026 
0000852c: 3400000c 0883d086 6c636ca7 24006c1f 
0000853c: 65167bcd ebc00bf8 00000116 0000783c 
0000854c: 00001af4 0000000c ffffff1c ffffff1c 
0000855c: db6e14d2 10882002 94603500 654e2d00 
0000856c: 2c030c06 94607bcd 0bfc654e 00001492 
0000857c: 000014d0 00009f1c 00001490 00000000 
0000858c: 00000000 ddee1422 db6e2000 04032000 
0000859c: 00000000 ff4ce3ff 4820c400 00000404 
[ 1601.498888] 
KERNEL STACK:
bf0b1f28: bea0e9b4 bf0b1f58 bf0b1f5c 806a1426 
bf0b1f38: 00000000 00000000 bf0b1f68 7fb0de14 
bf0b1f48: 00000001 bf0b1f5c 8004afec bf0b1f68 
bf0b1f58: 00000000 7fb0dd3c 8004a418 00008500 
bf0b1f68: 2aac8a18 2aae22aa 000084ec 00020340 
bf0b1f78: 7fb0dd38 00000001 00000001 7fb0de14 
bf0b1f88: 00000001 fffffffe 00008500 00000000 
bf0b1f98: 00000000 00000000 7fb0dd3c 000c873c 
bf0b1fa8: 00008380 00000000 001030dc 001030ac 
bf0b1fb8: ffffffff 00000000 2abfa20c 00000000 
bf0b1fc8: 00000000 00000000 7fb0da10 2aaa8736 
bf0b1fd8: 2aacdb9c 00000000 00000000 7fb0dd50 
[ 1601.552499] 
Call Trace:
Segmentation fault (core dumped)

分析生成的core文件,可以发下问题点在*p = 1;:

#0  0x000084ec in main () at buserror.c:7
        p = 0xfffffffe <error: Cannot access memory at address 0xfffffffe>

再结合objdump和CODE段验证对比,同样结果。

000084d0 <main>:
#include <stdio.h>

void main(void)
{
    84d0:       1421            subi            sp, sp, 4
    84d2:       dd0e2000        st.w            r8, (sp, 0)
    84d6:       6e3b            mov             r8, sp
    84d8:       1421            subi            sp, sp, 4
        char *p = (char *)0xfffffffe;
    84da:       e4481003        subi            r2, r8, 4
    84de:       3300            movi            r3, 0
    84e0:       2b01            subi            r3, 2
    84e2:       b260            st.w            r3, (r2, 0)

        *p = 1;
    84e4:       e4681003        subi            r3, r8, 4
    84e8:       9360            ld.w            r3, (r3, 0)
    84ea:       3201            movi            r2, 1
    84ec:       a340            st.b            r2, (r3, 0)
    84ee:       db630000        ld.b            r27, (r3, 0)
}

 

2. 函数指针异常

构造函数指针异常,即函数指针指向了内核一段空间。

#include <stdio.h>

void main(void)
{
    void *(*pf)(void);
    pf = 0xfffffffe;
    pf();
    printf("EOP");
}

执行后异常输出如下:

[ 3818.626608] User mode Bus Error
[ 3818.629786] 
[ 3818.629786] CURRENT PROCESS:
[ 3818.629786] 
[ 3818.635635] COMM=buserror PID=415
[ 3818.638960] TEXT=00008000-00008604 DATA=00009f1c-0000a018 BSS=0000a018-0000b000
[ 3818.646276] USER-STACK=7fcf3e10  KERNEL-STACK=be829700
[ 3818.646276] 
[ 3818.652907] PC: 0xfffffffe (0xfffffffe)-------------------------------这里的PC指针并没有指向代码段,也即函数跳转到内核空间了。
[ 3818.656750] LR: 0x00008524 (0x8524)-----------------------------------重点需要查看LR指针指向的位置。
[ 3818.660241] SP: 0xbf197f68 
[ 3818.663038] orig_a0: 0x00000001
[ 3818.666183] PSR: 0x00020340
[ 3818.668986]  a0: 0x00000001   a1: 0x7fcf3e14   a2: 0x7fcf3d34   a3: 0xfffffffe
[ 3818.676218]  r4: 0x00008548   r5: 0x00000000   r6: 0x00000000   r7: 0x00000000
[ 3818.683448]  r8: 0x7fcf3d38   r9: 0x000c873c  r10: 0x000083b0  r11: 0x00000000
[ 3818.690677] r12: 0x001030dc  r13: 0x001030ac  r15: 0x00008524
[ 3818.696430] r16: 0xffffffff  r17: 0x00000000  r18: 0x2abfa20c  r19: 0x00000000
[ 3818.703662] r20: 0x00000000  r21: 0x00000000  r22: 0x7fcf3a10  r23: 0x2aaa8736
[ 3818.710892] r24: 0x2aacdb9c  r25: 0x00000000  r26: 0x00000000  r27: 0xfffffffe
[ 3818.718122] r28: 0x2abf7000  r29: 0x00000000  r30: 0x00000000  tls: 0x2aac8a18
[ 3818.725350]  hi: 0x00000000   lo: 0x00000000 
[ 3818.729709] 
CODE:
ffffffc0: [ 3818.732827] Unable to handle kernel paging request at virtual address 0xfffff000, pc: 0x8004bdc4
[ 3818.741647] Oops: 00000000
[ 3818.744373] 
[ 3818.744373] CURRENT PROCESS:
[ 3818.744373] 
[ 3818.750233] COMM=buserror PID=415
[ 3818.753568] TEXT=00008000-00008604 DATA=00009f1c-0000a018 BSS=0000a018-0000b000
[ 3818.760899] USER-STACK=7fcf3e10  KERNEL-STACK=be829700
[ 3818.760899] 
[ 3818.767549] PC: 0x8004bdc4 (show_regs+0x188/0x340)
[ 3818.772374] LR: 0x8004beb8 (show_regs+0x27c/0x340)
[ 3818.777183] SP: 0xbf197e0c 
[ 3818.779993] orig_a0: 0x0000000b
[ 3818.783137] PSR: 0x80140300
[ 3818.785951]  a0: 0x0000000b   a1: 0x00000000   a2: 0x808fec04   a3: 0x00000000
[ 3818.793196]  r4: 0x00000000   r5: 0xffffffc0   r6: 0xbf197f68   r7: 0x808494c4
[ 3818.800441]  r8: 0xbf197eb0   r9: 0x808494b8  r10: 0x000083b0  r11: 0x00000000
[ 3818.807684] r12: 0x00000004  r13: 0x8007f6c8  r15: 0x8004beb8
[ 3818.813457] r16: 0xffffffff  r17: 0x00000000  r18: 0xbf1add8c  r19: 0x0000027f
[ 3818.820702] r20: 0x00000004  r21: 0xffffffe4  r22: 0x00000000  r23: 0x0000001b
[ 3818.827945] r24: 0x00000000  r25: 0x80718358  r26: 0x8004f940  r27: 0x00000020
[ 3818.835190] r28: 0x2abf7000  r29: 0x00000000  r30: 0x00000000  tls: 0x00000000
[ 3818.842434]  hi: 0x000000f8   lo: 0xd57a2000 
[ 3818.846807] 
CODE:
8004bd84: d8464820 d8262024 12022023 051ae005 
8004bd94: 4820c400 e0051200 c4000515 96a24820 
8004bda4: e4652d3f 3b402003 0503c400 614c4361 
8004bdb4: ea893400 11fa003a 200fe464 0078e903 
8004bdc4: 6c1f9520 e0052403 c40004fd eb444820 
8004bdd4: 25030100 11130bf2 04f4e005 4820c400 
8004bde4: e0051111 c40004ef e4a64820 3400103f 
8004bdf4: 002aea89 e46411ea e903200f 95200060 
8004be04: 24036c1f 04dee005 4820c400 00c0eb44 
8004be14: 0bf22503 e0051103 c40004d5 962e4820 
8004be24: e0003000 c40000f9 6fa34820 2006d92e 
8004be34: 98c498e5 988298a3 2001d9ee 2000d90e 
8004be44: 783c1407 8004f950 80061080 800607b0 
8004be54: 808491d4 800ec7c4 808491ec 80849258 
8004be64: 80849270 80849288 80849298 808492ac 
8004be74: 808492bc 808492f8 80849334 80849370 
[ 3818.916915] 
KERNEL STACK:
bf197dcc: bf1add8c 0000027f 00000004 ffffffe4 
bf197ddc: 00000000 0000001b 00000000 bf197eb0 
bf197dec: 80049f68 00000000 ffffffc0 bf197f68 
bf197dfc: 808494c4 808494b8 000083b0 00000000 
bf197e0c: 00000000 8004beb8 8004bdc4 80140300 
bf197e1c: 7fcf3d34 0000000b 0000000b 00000000 
bf197e2c: 808fec04 00000000 00000000 ffffffc0 
bf197e3c: bf197f68 808494c4 bf197eb0 808494b8 
bf197e4c: 000083b0 00000000 00000004 8007f6c8 
bf197e5c: ffffffff 00000000 bf1add8c 0000027f 
bf197e6c: 00000004 ffffffe4 00000000 0000001b 
bf197e7c: 00000000 80718358 8004f940 00000020 
[ 3818.970702] 
Call Trace:
[<8004af18>] buserr+0x54/0x80
[<8004afec>] trap_c+0xa8/0xe4
[<8004a418>] csky_trap+0x68/0x70
Segmentation fault

从错误log看出LR指向0x00008524 ,也即printf(""EOP);。所以问题出在pf();。

void main(void)
{
    8500:       1422            subi            sp, sp, 8
    8502:       dd0e2000        st.w            r8, (sp, 0)
    8506:       ddee2001        st.w            r15, (sp, 0x4)
    850a:       6e3b            mov             r8, sp
    850c:       1421            subi            sp, sp, 4
        void *(*pf)(void);
        pf = 0xfffffffe;
    850e:       e4481003        subi            r2, r8, 4
    8512:       3300            movi            r3, 0
    8514:       2b01            subi            r3, 2
    8516:       b260            st.w            r3, (r2, 0)
    8518:       db622000        ld.w            r27, (r2, 0)
        pf();
    851c:       e4681003        subi            r3, r8, 4
    8520:       9360            ld.w            r3, (r3, 0)
    8522:       7bcd            jsr             r3
        printf("EOP");
    8524:       1007            lrw             r0, 0x85fc      // 8540 <main+0x40>
    8526:       eae00008        jsri            0x0     // from address pool at 0x8544
    852a:       c4004820        lsli            r0, r0, 0
}

 

3.小结

综上所述遇到“User mode Bus Error”类型的错误,可以通过查看PC指针。

如果PC明显不是指向代码段,查看LR地址。这样就可以大概找出问题点。

期间需要借助objdump、hexdump等工具。

 

posted on 2019-05-12 00:00  ArnoldLu  阅读(1669)  评论(0编辑  收藏  举报

导航