gdb 除錯段錯誤

2021-05-25 00:59:19 字數 3222 閱讀 9486

開發嵌入式linux的時候經常會遇到segmentation fault,也就是段異常錯誤,一般是使用錯誤的指標訪問記憶體導致。這種錯誤可以通過開啟核心的異常資訊輸出,再用gdb對發生段異常的位址進行定位。

1.開啟核心的異常資訊輸出:

mips的核心**關閉了arch/mips/mm/fault.c的do_page_fault():133中的這段**:

#if 0

printk("do_page_fault() #2: sending sigsegv to %s for "

"invalid %s/n%0*lx (epc == %0*lx, ra == %0*lx)/n",

tsk->comm,

write ? "write access to" : "read access from",

field, address,

field, (unsigned long) regs->cp0_epc,

field, (unsigned long) regs->regs[31]);

#endif

#if 1

printk("do_page_fault() #2: sending sigsegv to %s for "

"invalid %s/n%0*lx (epc == %0*lx, ra == %0*lx)/n",

tsk->comm,

write ? "write access to" : "read access from",

field, address,

field, (unsigned long) regs->cp0_epc,

field, (unsigned long) regs->regs[31]);

show_registers(regs);

dump_stack();

#endif

2.定位發生段異常的**

列印的出錯資訊:

do_page_fault() #2: sending sigsegv to myprog for invalid read access from

00000004 (epc == 00479628, ra == 00482228)

.......

lo    : 00000001

epc   : 00479628 0x479628     not tainted

ra    : 00482228 0x482228

status: 0000f413    user exl ie 

cause : 00800008

badva : 00000004

prid  : 00019374

modules linked in: pppoe ppp_async ppp_deflate ppp_mppe pppox ppp_generic slhc

process myprog (pid: 7487, threadinfo=81096000, task=811135b8)

stack : 2ab4f360 00000001 100055a0 004d0000 1000b320 004d0000 100055a0 00482228

10036248 004d0000 2ab4f360 00000001 1000b320 004d0000 004cac44 004825f0

00000000 004ba948 004bebe0 004ccce8 004cac44 000000a8 100055a4 0043886c

1000b320 0040d8d0 00000000 0040d8d0 00000000 10003494 0040ddfc 0040dd18

004b2250 004b2278 004b2284 0040d83c 1000b320 00000000 1000b320 7fcdff80

...call trace:

code: 00000000  1090000a  00000000 <8c820004> 8c830000  8f998078  ac430000  0320f809  ac620004 

call trace:

[<8006dc04>] do_page_fault+0x214/0x430

[<8006dbfc>] do_page_fault+0x20c/0x430

[<800a881c>] handle_irq_event+0x70/0xfc

[<800a89e4>] __do_irq+0x13c/0x158

[<8006e328>] tlb_do_page_fault_0+0xf8/0x100

[<8006130c>] ar7100_interrupt_receive+0xec/0x100

segmentation fault

可以看到,發生異常的程式位址(epc暫存器)是0x00479628,程式返回位址(ra暫存器)是0x00482228。使用gdb來定位,注意編譯myprog程式時要帶編譯引數-g -ggdb,否則myprog中沒有除錯資訊。

#mipseb-linux-uclibc-gdb myprog

(gdb) l *(0x00479628)

0x479628 is in dropall (../../../include/util.h:107).

102      *

103      * this is only for internal list manipulation where we know

104      * the prev/next entries already!

105      */

106     static inline void __list_del(struct list_head *prev, struct list_head *next)

107     

111(gdb) l *(0x00482228)

0x482228 is in fw_cleanenv (firewall.c:325).

320         

323324         /* ?3? ¢ */

325         dropall(&g_llandev);

326          dropall(&g_lwandev);

327     }

328329

可以看到fw_cleanenv()中的第325行呼叫的dropall(&g_llandev)導致了段異常,具體是在dropall()使用的util.h:107的巨集

__list_del()產生的異常。

gdb 除錯段錯誤

利用執行時產生core檔案,再利用gdb除錯找出段錯誤在哪一行 ulimit c unlimited使用該bash命令,可以使執行時段錯誤產生core檔案。1.gcc g 編譯 gcc g o a a.c2.執行檔案,便會產生乙個core.檔案 a3.除錯core檔案 gdb a core.便可以直...

gdb除錯段錯誤

一 gdb的除錯命令。c語言是 cc g tst.c o tst c 是g g o 生成的檔案 file.cpp c 除錯程式命令 gdb file 啟動,羅列 行數ist 1,break 行數 info break,run r 除錯執行,step s 單步除錯,檢視變數 print p 變數名,檢...

GDB除錯段錯誤

一 gdb的除錯命令。c語言是 cc g tst.c o tst c 是g g o 生成的檔案 file.cpp c 除錯程式命令 gdb file 啟動,羅列 行數ist 1,break 行數 info break,run r 除錯執行,step s 單步除錯,檢視變數 print p 變數名,檢...