linux ip head check sun,linux panic 问题定位
詳細描述出現kernel panic時的處理過程。
最直接、簡單的方法,查看panic時的調用棧,根據打印的出錯函數及文件行數,找到panic的位置,再詳細處理。
有時候會出現錯誤的調用棧,此時必須查看出錯的指令地址,對于x86架構來說,就是EIP,同時關注調用棧的地址。在調用棧錯誤時,可以手工將地址轉換成出錯函數及行數,以下分兩個部分介紹:
大部分kernel panic都是由于可加載卸載的內核模塊導致,此時可以通過如下步驟將地址翻譯成具體代碼位置。
1.?????獲取內核模塊基地址
查看/proc/modules,找到關注的內核模塊的基地址,如下是一個示例
root@miner:~#cat /proc/modules | grep mm
mm ? ? ? ? ? 643877 0 - Live 0xd27cf000 (O)
mm_if ????? 1526 ???? 1mm, Live 0xd27b8000 (O)
絕大部分情況下,系統在重啟后,模塊的基地址不會改變。如上圖所示,mm模塊的地址空間從基地址0xd27cf000開始,大小為643877,如果某個地址落在這個區間,則確定為此模塊的地址。
2.?????計算地址偏移
將出錯的內核地址減去模塊基地址,即得到偏移地址。
3.?????生成模塊可調試文件
確保編譯內核時EXTRA_CFLAGS參數添加-g,如此編譯后會生成內核模塊對應的.o文件(假設為hello.o),使用編譯工具鏈ld(交叉編譯時需要使用交叉編譯工具鏈),命令如下:
ld -r -d -o hello.ko.debug hello.o
4.?????gdb調試
gdbhello.ko.debug
假設偏移地址為0xa7d0,則info line*0xa7d0便得到panic時的位置信息。
如果出錯地址為內核,則不需要計算偏移地址,直接使用出錯地址即可。,使用gdb 調試vmlinux,注意不是vmlinuz,方法基本與內核模塊類似
l??現象
insmod 模塊報“operation not permitted”,很快出現panic 信息。此問題為與客戶聯調時現場出現。
l??定位
此問題最終原因是模塊初始化時接口返回值混亂導致,實際上此模塊已經成功插入到內核,但是因為返回值混亂,導致判斷是插入模塊失敗,因此當前內核模塊退出,此內核模塊的代碼段卸載,但此內核模塊注冊到內核報文處理過程沒有被正確卸載,故在報文收發時因為沒有可用的代碼段導致panic。
l??現象
設備在報文有流量的情況下下發配置到內核,會小概率性的出現panic,panic時串口顯示“rcu_preempt self-detected stall on CPU”
l??定位
此問題最終原因是內核死鎖。有兩個過程需要同步,一個是報文收發軟中斷,另一個是命令下發過程(進程上下文),代碼中使用spin_lock 同步。
在命令下發過程中,鎖已經獲取,但恰好此時有一個軟中斷到來,打斷了命令下發過程,而且在軟中斷過程中需要獲取相同的鎖,此鎖已經被命令下屬過程占住,因此導致死鎖。解決方法很簡單,在命令下發過程中禁止軟中斷,即使用spin_lock_bh 同步。
l??現象
短時間內,內核模塊卸載再加載后,會隨機小概率的出現panic
l??定位
內核模塊會在流結構中存儲若干內容,包括分配的結點指針等。當內核模塊卸載之后,這條流一直存在沒有結束;當內核模塊兩次加載后,這條流又被處理,使用了前一次無效的結點指針,導致panic。
此問題通過“模塊引用”計數方案解決,當內核模塊卸載再加載后,之前已經處理過的流直接bypass。
l??現象
網口down再up之后,小概率的出現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??定位
粗看發現htb_dequeue函數,后來仔細查看是在我們自己的內核模塊sch_per,是通過EIP地址轉換得到,不清楚此版本的Linux?kernel顯示調用棧為什么不完整。
具體原因是在網口down時,會釋放當前所有的IP結點,但是其活躍鏈表的鏈表頭沒有初始化,仍然指向了已經釋放的IP結點,導致網口再次up時,出現panic。
3. 現象
<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]
某一臺設備,經常性的panic(每天平均一次以上),但EIP記錄為0,無法獲得panic時的地址,通過翻譯調用棧地址,僅能得到在內核模塊的forward函數和local_in函數位置,詳細的panic位置無法獲取。
粗略查看,panic有兩種情況,一種是在0xf89237d0,另一種是在0xf89237bb,目前已知maxnet-dpi.ko 的基地址為0xf8919000,這兩種情況如下:
(1) 0xf89237d0
此地址(偏移地址為0xa7d0)定位到函數 app_local_in 的第一行,反匯編后查看,發現指令如下:
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)導致panic,如果其地址可信,懷疑可能是硬件問題。
(2) 0xf89237bb
此地址定位到maxnet_dpi_proc函數的最后一行,即maxnet_dpi_forward調用處
此問題僅在一臺設備上出現,且此設備為很多年前的、不發貨僅供測試的設備,也可能是硬件問題
此問題待定,目前尚未解決!!!!!!!
l? 現象2
程序在某臺網關設備上頻繁重啟,相關日志如下:
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]
查看出錯代碼位置的反匯編,發現對應的代碼段如下:
*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;
出錯的指令地址對應紅色代碼,但上方不遠處有相同的代碼,故認為是DHCP處理函數(dpi_osinfo_refresh_hostname)導致,詳細查看代碼,發現其內部的子函數在memcpy 時沒有注意長度,會導致棧數組越界。
棧越界時,會將很多信息破壞,包括調用棧、返回指針,所以之前看到的panic,連EIP都是錯的,以后如果看到調用棧損壞、EIP非法,就可以考慮是否為棧越界。
總結
以上是生活随笔為你收集整理的linux ip head check sun,linux panic 问题定位的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux记录iptables日志,ip
- 下一篇: linux下dup函数,Linux du