一次MIPS架构嵌入式程序段错误调试过程
一个遗留的程序跑了一段时间就报:
Segmentation fault
本文章记录如何从内核输出的信息中查找是那个函数导致段错误的函数。
程序报错
程序tt_tf运行一段时间,报错停止:
[2] - Segmentation fault ./tt_tf
查看错误信息
输入dmesg命令,查看错误信息。
[root@Ingenic-uc1_1:~]# dmesg
[root@Ingenic-uc1_1:~]#[52896.532262] do_page_fault(): sending SIGSEGV to rr_tf for invalid read access from 00000000
[root@Ingenic-uc1_1:~]#[52896.532278] epc = 778aec88 in libuClibc-0.9.33.2.so[77872000+a9000]
[root@Ingenic-uc1_1:~]#[52896.532309] ra = 77cc2a6c in libttdb.so[77cc1000+6000]
从错误信息可以看出是libttdb.so库中的函数内存访问异常了。
反汇编
在代码编译环境中反汇编libttdb.so。
rr@rr-PowerEdge:/home/rr/$mips-linux-uclibc-objdump -d libttdb.so >ttdb_dump.txt
查找导致段错误的函数
根据错误信息中的:
> ra = 77cc2a6c in libttdb.so[77cc1000+6000]
得出地址 0x1a6c(0x77cc2a6c - 0x77cc1000 = 0x1a6c),在反汇编的输出文件(ttdb_dump.txt)中查找该地址(1a6c)。
790 1a38: 1840000e blez v0,1a74 <get_old_filename+0x184>
791 1a3c: 8f998074 lw t9,-32652(gp)
792 1a40: 8f848028 lw a0,-32728(gp)
793 1a44: 8f9980ec lw t9,-32532(gp)
794 1a48: 8fc50004 lw a1,4(s8)
795 1a4c: 0320f809 jalr t9
796 1a50: 24843eac addiu a0,a0,16044
797 1a54: 8fbc0018 lw gp,24(sp)
798 1a58: 8fbe00c0 lw s8,192(sp)
799 1a5c: 02002025 move a0,s0
800 1a60: 8f9980f0 lw t9,-32528(gp)
801 1a64: 0320f809 jalr t9
802 1a68: 8fc50004 lw a1,4(s8)
803 1a6c: 8fbc0018 lw gp,24(sp)
804 1a70: 8f998074 lw t9,-32652(gp)
该地址在函数get_old_filename中,即在该函数中某个地方导致的段错误。