[問題] null function pointer 造成 epc=0

看板C_and_CPP作者時間8年前 (2015/10/27 17:54), 編輯推噓2(204)
留言6則, 2人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) C, OpenWrt, MIPS74Kc 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) 問題(Question): 我們遇到一個kernel paging request crash. 會造成epc == 00000000, ra == 00000000的結果. 如下 CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 00000000, ra == 00000000 Oops[#1]: Cpu 0 $ 0 : 00000000 00000001 00000000 00000101 $ 4 : 87234000 00000000 85c7b0dc 8030f5ec $ 8 : 00000060 00000001 063cbd80 00000080 $12 : 00000000 00000000 00000008 00b00000 $16 : 00000000 00000000 00000000 00000000 $20 : 00000000 00000000 00000000 00000000 $24 : 00010000 86244570 $28 : 8030e000 8030f948 8030faa8 00000000 Hi : 00000005 Lo : 0000000c epc : 00000000 (null) Tainted: P ra : 00000000 (null) Status: 1100ff03 KERNEL EXL IE Cause : 00800008 BadVA : 00000000 Call Trace: [<873002e4>] ath_hal_reg_read+0x38/0x4c [ath_hal] [<862666e4>] ieee80211_input+0x1564/0x16f4 [umac] [<873002ac>] ath_hal_reg_read+0x0/0x4c [ath_hal] [<8733ca24>] ar9300_set_interrupts+0x3a0/0x73c [ath_hal] [<8620f164>] ieee80211_crypto_encap+0x1a8/0x320 [umac] 我們使用"objdump -d"試圖去查詢函式ath_hal_reg_read() 得到 2a8: 00000000 nop 000002ac <ath_hal_reg_read>: 2ac: 27bdffe0 addiu sp,sp,-32 2b0: 3c060000 lui a2,0x0 2b4: afbf001c sw ra,28(sp) 2b8: 00a03821 move a3,a1 2bc: afb00018 sw s0,24(sp) 2c0: 24c60000 addiu a2,a2,0 2c4: 8c8203ac lw v0,940(a0) 2c8: 00451021 addu v0,v0,a1 2cc: 24050002 li a1,2 2d0: 8c500000 lw s0,0(v0) 2d4: 3c020000 lui v0,0x0 2d8: 24420000 addiu v0,v0,0 2dc: 0040f809 jalr v0 2e0: afb00010 sw s0,16(sp) 2e4: 02001021 move v0,s0 2e8: 8fbf001c lw ra,28(sp) 2ec: 8fb00018 lw s0,24(sp) 2f0: 03e00008 jr ra 2f4: 27bd0020 addiu sp,sp,32 但仍無法分析原因為何? 更無法找到出錯的程式行 希望能找到問題出錯的程式動作 餵入的資料(Input): 預期的正確結果(Expected Output): 沒有kernel crash 錯誤結果(Wrong Output): 程式碼(Code):(請善用置底文網頁, 記得排版) u_int32_t __ahdecl ath_hal_reg_read(struct ath_hal *ah, u_int reg) { u_int32_t val; #if AH_REGREAD_DEBUG struct ath_hal_private *ahpriv; ahpriv = AH_PRIVATE(ah); int regbase, offset; #endif #ifdef AH_ANALOG_SHADOW_READ if (reg<=RF_END && reg>=RF_BEGIN) val = ah->ah_rfshadow[(reg-RF_BEGIN)/4]; else #endif val = _OS_REG_READ(ah, reg); #if AH_REGREAD_DEBUG /* In order to save memory, the size of the buff to record the register readings * equals to the register space divided by 8, with each the size is 8192 (0x2000), * and the ah_regaccessbase is from 0 to 7. */ regbase = reg >> 13; if (regbase == ahpriv->ah_regaccessbase) { offset = reg - (regbase<<13); ahpriv->ah_regaccess[offset] ++; } #endif HDPRINTF(ah, HAL_DBG_REG_IO, "READ 0x%x => 0x%x\n", reg, val); return val; } or u_int32_t __ahdecl ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg) { u_int32_t val; val = _OS_REG_READ(ah, reg); if (ath_hal_alq) { unsigned long flags; struct ale *ale; local_irq_save(flags); ale = ath_hal_alq_get(ah); if (ale) { struct athregrec *r = (struct athregrec *) ale->ae_data; r->op = OP_READ; r->reg = reg; r->val = val; alq_post(ath_hal_alq, ale); } local_irq_restore(flags); } return val; } 補充說明(Supplement): -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.132.176.115 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1445939672.A.E4E.html

10/27 19:56, , 1F
檢查 HDPRINTF 巨集所代換成的函式有沒有連結進來
10/27 19:56, 1F

10/27 19:57, , 2F
那個 jalr 看起來對應 HDPRINTF 呼叫
10/27 19:57, 2F

10/27 19:58, , 3F
但是它載入的是一個 null pointer 去 jalr 才會掛掉
10/27 19:58, 3F

10/27 19:59, , 4F
這看起來是連結時因為找不到目標函數所以留著空指標
10/27 19:59, 4F

10/28 12:07, , 5F
目前只看的出 0x2ac+0x38=0x2e4 那行有問題 (吧XD)
10/28 12:07, 5F

10/28 12:08, , 6F
建議用 -g build debug module, 會更好抓問題
10/28 12:08, 6F
文章代碼(AID): #1MBqdOvE (C_and_CPP)