linux ip head check sun,linux panic 问题定位
詳細(xì)描述出現(xiàn)kernel panic時的處理過程。
最直接、簡單的方法,查看panic時的調(diào)用棧,根據(jù)打印的出錯函數(shù)及文件行數(shù),找到panic的位置,再詳細(xì)處理。
有時候會出現(xiàn)錯誤的調(diào)用棧,此時必須查看出錯的指令地址,對于x86架構(gòu)來說,就是EIP,同時關(guān)注調(diào)用棧的地址。在調(diào)用棧錯誤時,可以手工將地址轉(zhuǎn)換成出錯函數(shù)及行數(shù),以下分兩個部分介紹:
大部分kernel panic都是由于可加載卸載的內(nèi)核模塊導(dǎo)致,此時可以通過如下步驟將地址翻譯成具體代碼位置。
1.?????獲取內(nèi)核模塊基地址
查看/proc/modules,找到關(guān)注的內(nèi)核模塊的基地址,如下是一個示例
root@miner:~#cat /proc/modules | grep mm
mm ? ? ? ? ? 643877 0 - Live 0xd27cf000 (O)
mm_if ????? 1526 ???? 1mm, Live 0xd27b8000 (O)
絕大部分情況下,系統(tǒng)在重啟后,模塊的基地址不會改變。如上圖所示,mm模塊的地址空間從基地址0xd27cf000開始,大小為643877,如果某個地址落在這個區(qū)間,則確定為此模塊的地址。
2.?????計算地址偏移
將出錯的內(nèi)核地址減去模塊基地址,即得到偏移地址。
3.?????生成模塊可調(diào)試文件
確保編譯內(nèi)核時EXTRA_CFLAGS參數(shù)添加-g,如此編譯后會生成內(nèi)核模塊對應(yīng)的.o文件(假設(shè)為hello.o),使用編譯工具鏈ld(交叉編譯時需要使用交叉編譯工具鏈),命令如下:
ld -r -d -o hello.ko.debug hello.o
4.?????gdb調(diào)試
gdbhello.ko.debug
假設(shè)偏移地址為0xa7d0,則info line*0xa7d0便得到panic時的位置信息。
如果出錯地址為內(nèi)核,則不需要計算偏移地址,直接使用出錯地址即可。,使用gdb 調(diào)試vmlinux,注意不是vmlinuz,方法基本與內(nèi)核模塊類似
l??現(xiàn)象
insmod 模塊報“operation not permitted”,很快出現(xiàn)panic 信息。此問題為與客戶聯(lián)調(diào)時現(xiàn)場出現(xiàn)。
l??定位
此問題最終原因是模塊初始化時接口返回值混亂導(dǎo)致,實(shí)際上此模塊已經(jīng)成功插入到內(nèi)核,但是因?yàn)榉祷刂祷靵y,導(dǎo)致判斷是插入模塊失敗,因此當(dāng)前內(nèi)核模塊退出,此內(nèi)核模塊的代碼段卸載,但此內(nèi)核模塊注冊到內(nèi)核報文處理過程沒有被正確卸載,故在報文收發(fā)時因?yàn)闆]有可用的代碼段導(dǎo)致panic。
l??現(xiàn)象
設(shè)備在報文有流量的情況下下發(fā)配置到內(nèi)核,會小概率性的出現(xiàn)panic,panic時串口顯示“rcu_preempt self-detected stall on CPU”
l??定位
此問題最終原因是內(nèi)核死鎖。有兩個過程需要同步,一個是報文收發(fā)軟中斷,另一個是命令下發(fā)過程(進(jìn)程上下文),代碼中使用spin_lock 同步。
在命令下發(fā)過程中,鎖已經(jīng)獲取,但恰好此時有一個軟中斷到來,打斷了命令下發(fā)過程,而且在軟中斷過程中需要獲取相同的鎖,此鎖已經(jīng)被命令下屬過程占住,因此導(dǎo)致死鎖。解決方法很簡單,在命令下發(fā)過程中禁止軟中斷,即使用spin_lock_bh 同步。
l??現(xiàn)象
短時間內(nèi),內(nèi)核模塊卸載再加載后,會隨機(jī)小概率的出現(xiàn)panic
l??定位
內(nèi)核模塊會在流結(jié)構(gòu)中存儲若干內(nèi)容,包括分配的結(jié)點(diǎn)指針等。當(dāng)內(nèi)核模塊卸載之后,這條流一直存在沒有結(jié)束;當(dāng)內(nèi)核模塊兩次加載后,這條流又被處理,使用了前一次無效的結(jié)點(diǎn)指針,導(dǎo)致panic。
此問題通過“模塊引用”計數(shù)方案解決,當(dāng)內(nèi)核模塊卸載再加載后,之前已經(jīng)處理過的流直接bypass。
l??現(xiàn)象
網(wǎng)口down再up之后,小概率的出現(xiàn)panic,出錯信息如下:
<1>[592005.836736]BUG:?unable?to?handle?kernel?NULL?pointer?dereference?at?00000001
<1>[592005.845688]IP:?[]?0xf89a6074
<4>[592005.846675]*pde?=?00000000
<4>[592005.846675]Oops:?0000?[#1]
<4>[592005.846675]Modules?linked?in:?algapi?[last?unloaded:?maxnet_dpi_if]
<4>[592005.846675]
<4>[592005.846675]Pid:?0,?comm:?swapper?Tainted:?G??????????O?3.3.8?#38?HOLL?Technologies????????/
<4>[592005.846675]EIP:?0060:[]?EFLAGS:?00010246?CPU:?0
<4>[592005.846675]EIP?is?at?0xf89a6075
<4>[592005.846675]EAX:?c19b6c08?EBX:?00000000?ECX:?00000000?EDX:?f59be000
<4>[592005.846675]ESI:?f59be000?EDI:?00000001?EBP:?c19b6c10?ESP:?f600bbac
<4>[592005.846675]??DS:?007b?ES:?007b?FS:?0000?GS:?0000?SS:?0068
<0>[592005.846675]Process?swapper?(pid:?0,?ti=f600a000?task=c14264c0?task.ti=c141e000)
<0>[592005.846675]Stack:
<4>[592005.846675]??00000000?fffffffe?00000000?c19b7600?c12b775dc1a9fb30?b554c74e?00000869
<4>[592005.846675]??c1a9fc30?c1a9f8c0?c1a9f800?00000000?0386df19c1a9f800?00000001?c1a9fb30
<4>[592005.846675]??c1a9fa30?b90e8051?00000869?c19b7600?c1a9fb30c1a9fa30?c1a9f910?c1a9f800
<0>[592005.846675]Call?Trace:
<4>[592005.846675]??[]???htb_dequeue+0x3ad/0x7a0
<4>[592005.846675]??[]???__qdisc_run+0x75/0xf0
l??定位
粗看發(fā)現(xiàn)htb_dequeue函數(shù),后來仔細(xì)查看是在我們自己的內(nèi)核模塊sch_per,是通過EIP地址轉(zhuǎn)換得到,不清楚此版本的Linux?kernel顯示調(diào)用棧為什么不完整。
具體原因是在網(wǎng)口down時,會釋放當(dāng)前所有的IP結(jié)點(diǎn),但是其活躍鏈表的鏈表頭沒有初始化,仍然指向了已經(jīng)釋放的IP結(jié)點(diǎn),導(dǎo)致網(wǎng)口再次up時,出現(xiàn)panic。
3. 現(xiàn)象
<1>[3872.496538]?BUG:?unable?to?handle?kernel?NULL?pointer?dereference?at???(null)
<1>[3872.504815]?IP:?[]???(null)
<4>[3872.506445]?*pde?=?00000000
<4>[3872.506445]?Oops:?0000?[#1]
<4>[3872.506445]?Modules?linked?in:?maxnet_dpi(O)?sch_per(O)
<4>[3872.506445]
<4>[3872.506445]?Pid:?0,?comm:?swapper?Tainted:?G???????????O?3.3.8?#44?MICRO-STAR?INTERNATIONALCO.,?LTD?MS-9641/MS-9641
<4>[3872.506445]?EIP:?0060:[<00000000>]?EFLAGS:?00010286?CPU:?0
<4>[3872.506445]?EIP?is?at?0x0
<4>[3872.506445]?EAX:?00000000?EBX:?00000000?ECX:?00000000?EDX:?c1a3d96d
<4>[3872.506445]?ESI:?00000000?EDI:?00000000?EBP:?00000000?ESP:?f680bce8
<4>[3872.506445]??DS:?007b?ES:?007b?FS:?0000GS:?0000?SS:?0068
<0>[3872.506445]?Process?swapper?(pid:?0,?ti=f680a000?task=c14264c0task.ti=c141e000)
<0>[3872.506445]?Stack:
<4>[3872.506445]??00000000?00000000?00000000f680bd08?f89237d0?f680bd40?f88fb0a2?c1a3d840
<4>[3872.506445]??00000000?00000000?0000000000000000?00000000?00000000?00000000?00000000
<4>[3872.506445]??00000000?00000000?0000000000000000?00000006?00000000?f88fb41c?c12c9500
<0>[3872.506445]?Call?Trace:
<4>[3872.506445]??[]??miner_qos_fini+0x240/0x600?[maxnet_dpi]
某一臺設(shè)備,經(jīng)常性的panic(每天平均一次以上),但EIP記錄為0,無法獲得panic時的地址,通過翻譯調(diào)用棧地址,僅能得到在內(nèi)核模塊的forward函數(shù)和local_in函數(shù)位置,詳細(xì)的panic位置無法獲取。
粗略查看,panic有兩種情況,一種是在0xf89237d0,另一種是在0xf89237bb,目前已知maxnet-dpi.ko 的基地址為0xf8919000,這兩種情況如下:
(1) 0xf89237d0
此地址(偏移地址為0xa7d0)定位到函數(shù) app_local_in 的第一行,反匯編后查看,發(fā)現(xiàn)指令如下:
0000a7d0 :
#ifndef MAXNET_CHINA_TELECOM
static int app_local_in(unsigned char*layer2_data, maxnet_tupleinfo_t *tuple, void *data)
{
a7d0:?????? 57????????????????????? push?? %edi
僅僅一個入棧動作(push %edi)導(dǎo)致panic,如果其地址可信,懷疑可能是硬件問題。
(2) 0xf89237bb
此地址定位到maxnet_dpi_proc函數(shù)的最后一行,即maxnet_dpi_forward調(diào)用處
此問題僅在一臺設(shè)備上出現(xiàn),且此設(shè)備為很多年前的、不發(fā)貨僅供測試的設(shè)備,也可能是硬件問題
此問題待定,目前尚未解決!!!!!!!
l? 現(xiàn)象2
程序在某臺網(wǎng)關(guān)設(shè)備上頻繁重啟,相關(guān)日志如下:
CPU?0?Unable?to?handle?kernel?pagingrequest?atvirtualaddress?587d7a98,?epc?==?c224ca68,?ra?==?c224cc0c
Oops[#1]:
Cpu?0
$?0??:?00000000?00000031?ffff0000?00000000
$?4??:?00000001?00000006?00000000?00000000
$?8??:?00007740?8bd8791a?00000010?64725049
$12??:?00000000?00000000?00000000?00000000
$16??:?7376694f?43394e4f?64725049?587d7a98
$20??:?c228ed60?c2290000?8b9e8100?00000004
$24??:?00000010?c128c3cc
$28??:?8d7d4000?8d7d7a38?8d7d7c28?c224cc0c
Hi???:?033e3b62
Lo???:?f4806fde
epc??:?c224ca68?maxnet_dpi_proc+0xa8/0x374?[m01_b01]
Tainted:?P???????????O
ra???:?c224cc0c?maxnet_dpi_proc+0x24c/0x374?[m01_b01]
Status:?10009903????KERNEL?EXL?IE
Cause?:?0000000c
BadVA?:?587d7a98
PrId?:?0002a080?(Broadcom?BMIPS4350)
Call?Trace:
[]maxnet_dpi_proc+0xa8/0x374?[m01_b01]
[]ips_check+0xc0/0x14c?[dpi]
查看出錯代碼位置的反匯編,發(fā)現(xiàn)對應(yīng)的代碼段如下:
*layer7_id=?0;
layer3_data?=IP_HEADER_FROM_MAC(layer2data);
eh?=?(structethheader*)?layer2data;
if(?IP_PROTO_UDP?==tupleinfo->proto?)?{
/*4.?we?check?the?hostnameby?DHCP?for?osinfo?detection?*/
if(?MAXNET_DPI_ENGINE_ON==?g_dpi_engine_conf.osinfo_engine_status?){
if((!tupleinfo->direct)&&
68?==ntohs(tupleinfo->sport)?&&
67?==ntohs(tupleinfo->dport)){
memcpy(mac_address,eh->h_source,?6);
dpi_osinfo_refresh_hostname(layer3_data,tupleinfo->sipv4,?mac_address);
}
}
}
*layer7_id=?0;
出錯的指令地址對應(yīng)紅色代碼,但上方不遠(yuǎn)處有相同的代碼,故認(rèn)為是DHCP處理函數(shù)(dpi_osinfo_refresh_hostname)導(dǎo)致,詳細(xì)查看代碼,發(fā)現(xiàn)其內(nèi)部的子函數(shù)在memcpy 時沒有注意長度,會導(dǎo)致棧數(shù)組越界。
棧越界時,會將很多信息破壞,包括調(diào)用棧、返回指針,所以之前看到的panic,連EIP都是錯的,以后如果看到調(diào)用棧損壞、EIP非法,就可以考慮是否為棧越界。
總結(jié)
以上是生活随笔為你收集整理的linux ip head check sun,linux panic 问题定位的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux记录iptables日志,ip
- 下一篇: linux下dup函数,Linux du