[問題] null function pointer 造成 epc=0
開發平台(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
10/27 19:56, 1F
→
10/27 19:57, , 2F
10/27 19:57, 2F
→
10/27 19:58, , 3F
10/27 19:58, 3F
→
10/27 19:59, , 4F
10/27 19:59, 4F
推
10/28 12:07, , 5F
10/28 12:07, 5F
→
10/28 12:08, , 6F
10/28 12:08, 6F