精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

紅帽Linux故障定位技術(shù)詳解與實例

系統(tǒng) Linux
在線故障定位就是在故障發(fā)生時, 故障所處的操作系統(tǒng)環(huán)境仍然可以訪問,故障處理人員可通過console, ssh等方式登錄到操作系統(tǒng)上,在shell上執(zhí)行各種操作命令或測試程序的方式對故障環(huán)境進行觀察,分析,測試,以定位出故障發(fā)生的原因。

紅帽Linux故障定位技術(shù)詳解與實例是本文要介紹的內(nèi)容,主要是來了解并學習紅帽linux故障定位技術(shù)的學習,故障定位技術(shù)分為在線故障定位和離線故障定位,一起來看詳解。

1、故障定位(Debugging)場景分類

為便于描述問題,將Linux上各種軟件故障定位的情形分成兩類

(1)在線故障故障定位

在線故障定位(online-debugging)就是在故障發(fā)生時, 故障所處的操作系統(tǒng)環(huán)境仍然可以訪問,故障處理人員可通過console, ssh等方式登錄到操作系統(tǒng)上,在shell上執(zhí)行各種操作命令或測試程序的方式對故障環(huán)境進行觀察,分析,測試,以定位出故障發(fā)生的原因

(2)離線故障定位

離線故障定位(offline-debugging)就是在故障發(fā)生時,故障所處的操作系統(tǒng)環(huán)境已經(jīng)無法正常訪問,但故障發(fā)生時系統(tǒng)的全部或部分狀態(tài)已經(jīng)被系統(tǒng)本身所固有或事先設(shè)定的方式收集起來,故障處理人員可通過對收集到的故障定位狀態(tài)信息進行分析,定位出故障發(fā)生的原因

2、應用進程故障情形及處理

應用進程的故障一般不會影響操作系統(tǒng)運行環(huán)境的正常使用(如果應用代碼的bug導致了內(nèi)核的crash或hang,則屬于內(nèi)核存在漏洞),所以可采用在線故障定位的方法,靈活的進行分析. 應用代碼故障的情形有如下幾種:

(1)進程異常終止

很多用戶認為進程異常終止情況無從分析,但實際上進程異常終止情況都是有跡可尋的. 所有的進程異常終止行為,都是通過內(nèi)核發(fā)信號給特定進程或進程組實現(xiàn)的. 可分成幾個類型進行描述:

- SIGKILL. SIGKILL最特殊,因為該信號不可被捕獲,同時SIGKILL不會導致被終止的進程產(chǎn)生core文件, 但如果真正的是由內(nèi)核中發(fā)出的SIGKILL,則內(nèi)核一定會在dmesg中記錄下信息. 另外在內(nèi)核中使用SIGKILL的地方***,如oom_kill_process()中, 所以通過dmesg記錄并且分析內(nèi)核中使用SIGKILL的代碼,并不難分析原因

- SIGQUIT, SIGILL, SIGABRT, SIGBUS, SIGFPE, SIGSEGV. 這幾個信號在保留情況下會終止進程并會產(chǎn)生core文件, 用戶根據(jù)core中的stack trace信息,能直接定位出導致終止信號的代碼位置. 另外, SIGQUIT,SIGABRT一般是由用戶代碼自己使用的,好的代碼一般會記錄日志. SIGILL, SIGBUS, SIGFPE, SIGSEGV, 都是由內(nèi)核中產(chǎn)生的,搜索內(nèi)核源碼,不難列出內(nèi)核中使用這幾個信號的地方, 如SIGILL 是非法指令,可能是浮點運算產(chǎn)生的代碼被corrupted或文本區(qū)域的物理內(nèi)存corruption; SIGBUS多由MCE故障定位導致; SIGSEGV多由應用代碼的指針變量被corrupted導致. 對于應用的heap或stack的內(nèi)存被corrupted, 可用valgrind工具對應用進行profile, 通常能直接發(fā)現(xiàn)導致corruption的代碼

- SIGINT, SIGPIPE, SIGALRM, SIGTERM. 這幾個信號在保留情況下終止進程但不會產(chǎn)生core文件. 對這幾個信號,建議用戶一定要定義一個handler,以記錄產(chǎn)生問題的上下文. 比較容易忽略的是SIGPIPE, 很多用戶程序在使用select()或poll()時只監(jiān)聽read/write描述符,不監(jiān)聽exception描述符,在對方TCP已經(jīng)關(guān)閉的情況下,仍然向socket中寫入,導致SIGPIPE.

- 對于惡意的代嗎產(chǎn)生的進程終止行為,如合作的一些進程中,A向B發(fā)SIGKILL, 而沒做日志記錄,或者B直接判斷某條件而調(diào)用exit(), 也沒有做日志記錄.在應用代碼量很大的情況下,通過分析代碼故障定位這種情形也許很難. SystemTap提供了解決這個問題的一個比較好的方法,就是寫用戶層的probes, 追蹤進程對signal(), exit() 等系統(tǒng)調(diào)用的使用

(2)進程阻塞,應用無法正常推進

這種情況,對于單個被阻塞的進程而言,屬于正常狀態(tài), 但對于包含多個進程的應用整體而言,屬于異常. 應用無法推進,說明其中某一個進程推進的因素出現(xiàn)了問題,導致其他依賴于它的進程也要等待. 分析這種情形需要分析清楚進程或事件之間的依賴關(guān)系,及數(shù)據(jù)的處理流. 首先要用gdb -p 的back trace功能查出各進程阻塞的執(zhí)行路徑, 以確定每個進程所處在的狀態(tài)機的位置.

通常而言,如果只考慮各個進程的狀態(tài),則進程之間可能形成了一種互相依賴的環(huán)形關(guān)系,如(P1發(fā)請求=>P2處理=>P2發(fā)反應=>P1再請求=>P2處理=>P2再發(fā)反應), 但應用對workload, 一般是按一個個的transaction 或 session的方式進行處理的,每個transaction都有起點和終點, 我們需要用strace, tcpdump 等工具以及應用的執(zhí)行日志進行觀察,分析出當前正被處理的transaction所被阻滯的位置,從而找出全部狀態(tài)機被阻塞的原因. 導致這種狀態(tài)機停止運轉(zhuǎn)的原因有多個:如和應用通信的遠端出現(xiàn)了問題,后端數(shù)據(jù)庫/目錄等出現(xiàn)了問題,應用的某個進程或線程處于非正常的blocking位置或直接終止,不再正常工作.

(3)用戶進程形成死鎖

用戶進程形成死鎖,如果沒有內(nèi)存上的故障定位,則完全是應用自身的邏輯問題. 死鎖的進程或線程之間由于鎖的互相占有形成了環(huán)路。 這種情況發(fā)生時,用gdb -p 的back trace的功能能直接確定死鎖的進程全部阻塞在futex()等和鎖相關(guān)的系統(tǒng)調(diào)用上, 這些調(diào)用futex()的路徑可能是mutex, semaphore, conditional variable 等鎖函數(shù). 通過分析call trace 的代碼,能直接確定各進程在執(zhí)行到該位置時,可能已經(jīng)持有的全部鎖, 根據(jù)這個修改程序的代碼,消除死鎖環(huán)路,就可解決問題.

注意,內(nèi)存故障也可導致假的死鎖的,如物理內(nèi)存故障可直接導致鎖變量的值為-1, 所以使用該鎖的進程都會阻塞. 如果是代碼的bug導致的內(nèi)存corruption,可用valgrind工具檢查程序來發(fā)現(xiàn). 但如果是物理內(nèi)存的故障定位導致的corruption, 則需要硬件的支持,對于高端的PC, 如MCE功能的機器,當物理內(nèi)存故障定位時能直接產(chǎn)生異常或報告, 但對于低端PC服務器,除了運行memtest工具進行檢測外,沒有其他方法

(4)進程長期處于 'D' (UnInterruptible)狀態(tài)沒法退出

這種多是由內(nèi)核中的故障引起的. 內(nèi)核在很多執(zhí)行路徑中會將進程至于'D'的狀態(tài),以確保關(guān)鍵的執(zhí)行路徑不被外部的信號中斷, 導致不必要的內(nèi)核中數(shù)據(jù)結(jié)構(gòu)狀態(tài)的不一致性. 但一般而言,進程處于 'D' 狀態(tài)的時間不會太久, 因為狀態(tài)結(jié)束的條件(如timer觸發(fā),

IO操作完成等)很快會將進程喚醒. 當進程長期處于 'D',關(guān)鍵是要找出其阻塞的代碼位置, 用 sysrq 的t鍵功能可直接打印出系統(tǒng)中全部睡眠進程的內(nèi)核執(zhí)行堆棧,如 echo 't' > /proc/sysrq-trigger, 其中包括出現(xiàn) 'D'狀態(tài)的進程的內(nèi)核態(tài)堆棧. 找出代碼位置后,一般可直接分析出 'D' 狀態(tài)不能退出的原因, 如IO read操作因硬件或nfs故障而不能完成.

有可能導致 'D' 狀態(tài)的原因比較復雜,如‘D’的退出依賴于某變量的值,而該變量的值因某種原因被***corrupted掉了.

#p#

3、內(nèi)核故障情形及處理

(1)內(nèi)核panic

panic是內(nèi)核最直接的故障定位報告,發(fā)生panic時,內(nèi)核已經(jīng)認為故障定位已經(jīng)導致操作系統(tǒng)不再具備正常運行的條件了. 當發(fā)生panic時,Linux會將所有CPU的中斷和進程調(diào)度功能都關(guān)掉,所以這時系統(tǒng)是沒有任何反應的,如果用戶啟動的是圖形界面,則在屏幕上也看不到任何關(guān)于panic的信息.

我們通常遇到的,機器沒反應,ping不通的情況,絕大部分都是panic. Panic發(fā)生時,內(nèi)核直接在console上打印導致panic的代碼位置的調(diào)用堆棧, 傳統(tǒng)的用戶用串口連接到機器上來收集console上的打印信息, 但串口這種方式,顯然用起來不方便, 現(xiàn)在的Linux, 如RHEL5,RHEL6, 都采用kdump的方法來收集panic時的信息. 在配置好kdump的情況下,panic時系統(tǒng)會用kexec加載并切換到一個新的內(nèi)核上(放置在預先分配的內(nèi)存位置),并用磁盤或網(wǎng)絡(luò)等將系統(tǒng)的全部或部分內(nèi)存數(shù)據(jù)保存起來.

用kdump收集到panic的數(shù)據(jù)后,用戶用crash工具就能直接查看導致panic的代碼路徑.

panic一般是很直觀的,panic的堆棧信息能直接反映出導致bug的原因,如MCE故障,NMI故障, 數(shù)據(jù)結(jié)構(gòu)分配失敗等. 但有時panic是因為內(nèi)核主動發(fā)現(xiàn)了關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)不一致性,這種不一致性是什么時候,什么代碼導致的,并不清楚,可能還需要多次測試用SystemTap這樣的工具進行捕捉

(2)多處理機環(huán)境內(nèi)核執(zhí)行路徑產(chǎn)生的死鎖

內(nèi)核死鎖和panic不一樣,產(chǎn)生死鎖時,內(nèi)核并不主動的使自己處于掛起狀態(tài). 但內(nèi)核死鎖發(fā)生時,兩個以上的CPU的執(zhí)行路徑在內(nèi)核態(tài)不能推進了,處于互相阻塞狀態(tài), 而且是100%的占用CPU(用的spin-lock),直接或間接的導致全部CPU上的進程無法調(diào)度. 內(nèi)核死鎖又分兩種情況:

- 涉及到中斷上下文的死鎖. 這種情況的死鎖,最少一個CPU上的中斷被屏蔽了.系統(tǒng)可能沒法響應ping請求. 由于有一個CPU已經(jīng)沒法響應中斷,其上的local APIC定時中斷沒法工作,可以用NMI Watchdog的方法來檢測出來(檢查local APIC handler維護的計數(shù)器變量),NMI Watchdog可以在其處理程序中調(diào)用panic(), 用戶就可以用kdump收集內(nèi)存信息,從而分析各死鎖CPU上的調(diào)用堆棧,查處導致死鎖的邏輯原因.

- 不涉及中斷上下文的死鎖. 這種情況的死鎖,各CPU上的中斷都是正常的,系統(tǒng)能對ping請求作出反應,這時NMI Watchdog無法被觸發(fā). 在 2.6.16之前的內(nèi)核中,并沒有一種很好的方法來處理這種情形. 在RHEL5, RHEL6 內(nèi)核中, 每個CPU上提供了一個watchdog內(nèi)核線程,在死鎖出現(xiàn)的情況下,死鎖CPU上的watchdog內(nèi)核線程沒法被調(diào)度(即使它是***優(yōu)先級的實時進程),它就沒法update相應的counter變量,各CPU的NMI Watchdog中斷會周期性的檢查其CPU對應的counter, 發(fā)現(xiàn)沒有updated, 會調(diào)用panic(),用戶就可用kdump收集內(nèi)存信息,分析各死鎖CPU上的調(diào)用堆棧,查處導致死鎖的邏輯原因.

(3)內(nèi)核的oops或warning

oops 和warning和panic類似的地方是,他們都是因內(nèi)核發(fā)現(xiàn)了不一致而主動報告的異常. 但oops和warning導致的問題嚴重程度要比panic輕很多,以致于內(nèi)核處理該問題時不需要使系統(tǒng)掛起. 產(chǎn)生oops和warning, 內(nèi)核通常已經(jīng)在dmesg中記錄了相當?shù)男畔ⅲ貏e是oops, 至少會打印出現(xiàn)故障的地方的call trace. Oops也可轉(zhuǎn)換成panic/kdump來進行offline-debugging, 只要將/proc/sys/kernel下的panic_on_oops變量設(shè)置為1就行了.

產(chǎn)生oops和warning的直接原因有很多,如內(nèi)核中的segment fault, 或內(nèi)核發(fā)現(xiàn)的某數(shù)據(jù)結(jié)構(gòu)的counter值不對, 而segment fault 和counter值的變化還有更深層次的原因,通常并不能從內(nèi)核dmesg的信息中看出來,解決這種問題的是要用SystemTap進行probe, 如發(fā)現(xiàn)某counter的值不對,就用SystemTap做一個probe來記錄所有代碼對該counter的訪問, 然后再進行分析.

定位oops和warning會比定位應用程序的內(nèi)存訪問故障定位困難很多,因為在內(nèi)核并不能象用valgrind去trace應用程序一樣跟蹤數(shù)據(jù)結(jié)構(gòu)的分配和使用情況.

2、其他(硬件相關(guān))故障

機器自動重啟是一種常見的故障情形,一般是由硬件如物理內(nèi)存故障引起的,軟件的故障只會導致死鎖或panic, 內(nèi)核中幾乎沒有代碼在發(fā)現(xiàn)問題的情況下去reboot機器. 在/proc/sys/kernel目錄下有個參數(shù)“panic”, 其值如果設(shè)置為非0,則在panic發(fā)生若干秒后,內(nèi)核會重啟機器. 現(xiàn)在高端的PC服務器,都在努力用軟件來處理物理內(nèi)存故障,如MCA的 “HWPoison”方法會將故障的物理頁隔離起來,Kill掉故障頁所在的進程就可以了,RHEL6現(xiàn)在已經(jīng)支持 “HWPoison”. 那些不具備MCA能力的機器,物理內(nèi)存故障時,不會產(chǎn)生MCE異常,直接由硬件機制reboot機器

4、RHEL6 上的Debugging技術(shù)介紹

(1)Kdump故障定位收集和crash分析

kdump就是用來在內(nèi)核panic的情況下收集系統(tǒng)內(nèi)存信息的, 用戶也可在online情況下用sysrq的'c'鍵觸發(fā). Kdump 采用沒有污染的內(nèi)核來執(zhí)行dump工作,所以其比以前的diskdump, lkcd方法更可靠. 使用kdump,用戶可選擇將數(shù)據(jù)dump到本地盤或網(wǎng)絡(luò)上,也可通過定義makedumpfile的參數(shù)過濾要收集的內(nèi)存信息,已減少kdump所需要的停機時間

Crash就是對kdump的信息進行分析的工具.其實際就是gdb的一個wrapper. 使用crash時,***安裝kernel-debuginfo包,這樣能解析kdump收集的內(nèi)核數(shù)據(jù)的符號信息. 用crash來定位問題的能力,完全取決于用戶對內(nèi)核代碼的理解和分析能力

參考 “#>man kdump.conf”, “#>man crash”, “#>man makedumpfile”學習怎樣使用kdump和crash. 訪問 http://ftp.redhat.com可下載debuginfo文件

(2)用systemTap定位bug

systemtap 屬于probe類的定位工具,它能對內(nèi)核或用戶代碼的指定位置進行probe, 當執(zhí)行到指定位置或訪問指定位置的數(shù)據(jù)時,用戶定義的probe函數(shù)自動執(zhí)行,可打印出該位置的調(diào)用堆棧,參數(shù)值,變量值等信息. systemtap選擇進行probe的位置很靈活,這是systemtap的強大功能所在. Systemtap的probe點可包括如下幾個方面:

- 內(nèi)核中全部系統(tǒng)調(diào)用,內(nèi)核及模塊中全部函數(shù)的入口或出口點

- 自定義的定時器probe點

- 內(nèi)核中任意指定的代碼或數(shù)據(jù)訪問位置

- 特定用戶進程中任意制定的代碼或數(shù)據(jù)訪問位置

- 各個功能子系統(tǒng)預先設(shè)置的若干probe點,如tcp,udp,nfs,signal各子系統(tǒng)都預先設(shè)置了很多探測點

systemTap的腳本用stap腳本語言來編寫,腳本代碼中調(diào)用stap提供的API進行統(tǒng)計,打印數(shù)據(jù)等工作,關(guān)于stap語言提供的API函數(shù),參考 “#> man stapfuncs”. 關(guān)于systemTap的功能和使用可參考 “#> man stap”, “#> man stapprobes”

(3)ftrace

ftrace 是linux內(nèi)核中利用tracepoints基礎(chǔ)設(shè)施實現(xiàn)的事件追蹤機制,它的作用在于能比較清楚的給出在一定時間內(nèi)系統(tǒng)或進程所執(zhí)行的活動,如函數(shù)調(diào)用路徑,進程切換流等. Ftrace可用于觀察系統(tǒng)各部分的latency,以便進行實時應用的優(yōu)化; 它也可以通過記錄一段時間內(nèi)的內(nèi)核活動來幫助故障定位. 如用以下方法可trace某個進程在一端時間的函數(shù)調(diào)用情況

  1. #> echo “function” > /sys/kernel/debug/tracing/current_tracer  
  2. #> echo “xxx” > /sys/kernel/debug/tracing/set_ftrace_pid  
  3. #> echo 1 > /sys/kernel/debug/tracing/tracing_enabled 

除tracing函數(shù)調(diào)用外,ftrace還可tracing系統(tǒng)的進程切換,喚醒,塊設(shè)備訪問,內(nèi)核數(shù)據(jù)結(jié)構(gòu)分配等活動. 注意,tracing和profile是不同的,tracing記錄的是一段時間內(nèi)的全部活動,而不是統(tǒng)計信息,用戶可以通過/sys/kernel/debug/tracing下的buffer_size_kb設(shè)置緩沖區(qū)的大小, 以記錄更長時間的數(shù)據(jù).

關(guān)于ftrace的具體使用可參考內(nèi)核源碼Documenation/trace下的內(nèi)容

(4)oprofile 和 perf

oprofile和perf都是對系統(tǒng)進行profile(抽樣,統(tǒng)計)的工具,它們主要用來解決系統(tǒng)和應用的性能問題. perf功能更強大,更全面,同時perf的用戶空間工具和內(nèi)核源碼一起維護和發(fā)布,讓用戶能及時的享受perf內(nèi)核新增加的特征. Perf 是在RHEL6中才有,RHEL5中沒有Perf. Oprofile和perf 都使用現(xiàn)代CPU中具有的硬件計數(shù)器進行統(tǒng)計工作,但perf還可以使用內(nèi)核中定義的 “software counter”及 “trace points”, 所以能做更多的工作. Oprofile的抽樣工作利用 CPU的NMI中斷來進行,而perf既可以利用NMI中斷也可利用硬件計數(shù)器提供的周期性中斷. 用戶能很容易用perf來oprofile一個進程或系統(tǒng)的執(zhí)行時間分布,如

  1. #> perf top -f 1000 -p  

還可以利用系統(tǒng)定義的 “software counter”和各子系統(tǒng)的 “trace points” 對子系統(tǒng)進行分析, 如

  1. #>perf stat -a -e kmem:mm_page_alloc -e kmem:mm_page_free_direct -e kmem:mm_pagevec_free sleep 6 

能統(tǒng)計6秒內(nèi)kmem子系統(tǒng)的活動 (這一點實際是利用ftrace提供的tracepoints來實現(xiàn))

我認為有了perf, 用戶就沒必要使用oprofile了

#p#

5、用kdump工具內(nèi)核故障定位實例

A) 部署Kdump

部署 kdump 收集故障信息的步驟如下:

(1)設(shè)置好相關(guān)的內(nèi)核啟動參數(shù)

在 /boot/grub/menu.lst 中加入如下內(nèi)容

  1. crashkernel=128M@16M nmi_watchdog=1 

其中crashkernel參數(shù)是用來為kdump的內(nèi)核預留內(nèi)存的; nmi_watchdog=1 是用來激活NMI中斷的, 我們在未確定故障是否關(guān)閉了中斷的情況下, 需要部署NMI watchdog才能確保觸發(fā)panic. 重啟系統(tǒng)確保設(shè)置生效

(2)設(shè)置好相關(guān)的sysctl內(nèi)核參數(shù)

在/etc/sysctl.conf 中***加入一行

  1. kernel.softlookup_panic = 1  

該設(shè)置確保softlock發(fā)生時會調(diào)用panic, 從而觸發(fā)kdump行為執(zhí)行 #>sysctl -p 確保設(shè)置生效

(3)配置 /etc/kdump.conf

在 /etc/kdump.conf 中加入如下幾行內(nèi)容

  1. ext3 /dev/sdb1  
  2. core-collector makedumpfile -c –message-level 7 -d 31 -i /mnt/vmcoreinfo  
  3. path /var/crash  
  4. default reboot 

其中 /dev/sdb1 是用于放置dumpfile 的文件系統(tǒng), dumpfile 文件放置在/var/crash下, 要事先在/dev/sdb1分區(qū)下創(chuàng)建/var/crash 目錄. “-d 31”指定對dump內(nèi)容的過濾級別,這參數(shù)對于dump分區(qū)放不下全部內(nèi)存內(nèi)容或用戶不想讓dumping中斷業(yè)務太長時間時很重要. vmcoreinfo 文件放置在 /dev/sdb1 分區(qū)的 / 目錄下, 需要使用如下命令產(chǎn)生:

#>makedumpfile -g //vmcoreinfo -x /usr/lib/debug/lib/modules/2.6.18-128.el5.x86_64/vmlinux

“vmlinux” 文件是由kernel-debuginfo 包提供的,在運行makedumpfile 之前需要安裝相應內(nèi)核的 kernel-debuginfo 和 kernel-debuginfo-common 兩個包,該兩個包需從 http://ftp.redhat.com 下載. “default reboot” 用來告訴kdump, 收集完dump信息后重啟系統(tǒng)

(4)激活kdump

運行 #>service kdump start 命令,你會看到,在成功完成的情況下會在/boot/目錄下生成一個initrd-2.6.18-128.el5.x86_64kdump.img 文件,該文件就是kdump加載的內(nèi)核的 initrd文件,收集dump信息的工作就是在該initrd的啟動環(huán)境下進行的. 查看/etc/init.d/kdump腳本的代碼,你可看到其中會調(diào)用mkdumprd命令創(chuàng)建用于dump的initrd文件

1、測試Kdump部署的有效性

為了測試kdump部署的有效性,本人寫了如下一個內(nèi)核模塊,通過insmod 加載該內(nèi)核模塊, 就能產(chǎn)生一個內(nèi)核線程,在10秒左右后,占據(jù)100%的CPU,在20秒左右后觸發(fā)kdump. 系統(tǒng)重啟后,檢查/oracle分區(qū)/var/crash 目錄下的內(nèi)容,就能確認vmcore文件是否生成.

  1. Zqfthread.c #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7.  
  8. MODULE_AUTHOR("frzhang@redhat.com");   
  9. MODULE_DESCRIPTION("A module to test ....");   
  10. MODULE_LICENSE("GPL");   
  11.  
  12. static struct task_struct *zqf_thread;   
  13. static int zqfd_thread(void *data);   
  14.  
  15. static int zqfd_thread(void *data)   
  16. {   
  17. int i=0;   
  18.  
  19. while (!kthread_should_stop()) {   
  20. i++;   
  21. if ( i < 10 ) {   
  22. msleep_interruptible(1000);   
  23. printk("%d seconds\n", i);   
  24. }   
  25. if ( i == 1000 ) // Running in the kernel   
  26. i = 11 ;   
  27. }   
  28. return 0;   
  29. }   
  30. static int __init zqfinit(void)   
  31. {   
  32. struct task_struct *p;   
  33.  
  34. p = kthread_create(zqfd_thread, NULL,"%s","zqfd");   
  35.  
  36. if ( p ) {   
  37. zqf_thread = p;   
  38. wake_up_process(zqf_thread); // actually start it up   
  39. return(0);   
  40. }   
  41.  
  42. return(-1);   
  43. }   
  44.  
  45. static void __exit zqffini(void)   
  46. {   
  47. kthread_stop(zqf_thread);   
  48. }   
  49.  
  50. module_init(zqfinit);   
  51. module_exit(zqffini)  
  52.  
  53. Makefile obj-m += zqfthread.o  
  54. Making #> make -C /usr/src/kernels/2.6.32-71.el6.x86_64/ M=`pwd` modules 

2、用crash 工具分析vmcore 文件

用crash 命令分析vmcore 的命令行格式如下所示. 用crash打開vmcore后,主要是用dmesg及 bt 命令打印出問題的執(zhí)行路徑的call trace, 用dis 反匯編出代碼,最終確認call trace對應的C源碼中的位置,再進行邏輯分析.

  1. #>crash /usr/lib/debug/lib/modules/2.6.18-128.el5.x86_64/vmlinux /boot/System.map-2.6.18-128.el5.x86_64 ./vmcore 

#p#

6、使用kprobe來觀察內(nèi)核函數(shù)的執(zhí)行實例

kprobe是SystemTap對內(nèi)核函數(shù)進行probing的功能在內(nèi)核中的實現(xiàn),由于內(nèi)核中提供了正式的API來使用kprobe,所以對很多內(nèi)核程序員來說,也許直接使用kprobe比使用SystemTap更方便. 內(nèi)核中提供了三種類型的kprobe處理函數(shù),分別是jprobe, kprobe, kretprobe, 下面的代碼用這三個probe觀察在TCP/IP的arp_process函數(shù)執(zhí)行中對ip_route_input()調(diào)用的返回結(jié)果.這個代碼還展示了在同一個函數(shù)probe的Entry handler和Ret handler之間共享參數(shù)的方法. 代碼如下:

 

  1. arp_probe.c /*  
  2. * arp_probe.c, by Qianfeng Zhang (frzhang@redhat.com)  
  3. */  
  4.  
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10. #include   
  11. #include   
  12. #include   
  13.  
  14. MODULE_AUTHOR("frzhang@redhat.com");  
  15. MODULE_DESCRIPTION("A module to track the call results of ip_route_input() inside arp_process using jprobe and kretprobe");  
  16. MODULE_LICENSE("GPL");  
  17.  
  18. static int j_arp_process(struct sk_buff *skb)  
  19. {  
  20. struct net_device *dev = skb->dev;  
  21. struct in_device *in_dev;  
  22. int no_addr, rpf;  
  23.  
  24. in_dev = in_dev_get(dev);  
  25. no_addr = ( in_dev->ifa_list == NULL );  
  26. rpf = IN_DEV_RPFILTER(in_dev);  
  27. in_dev_put(in_dev);  
  28. printk("\narp_process() is called with interface device %s, in_dev(no_addr=%d,rpf=%d) \n", dev->name, no_addr, rpf);  
  29. jprobe_return();  
  30. return(0);  
  31. };  
  32.  
  33. static int j_fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,  
  34. struct net_device *dev, __be32 *spec_dst, u32 *itag, u32 mark)  
  35.  
  36. {  
  37. printk("fib_validate_source() is called with dst=0x%x, oif=%d \n", dst, oif);  
  38. jprobe_return();  
  39. return(0);  
  40. };  
  41.  
  42. static struct jprobe my_jp1 = {  
  43. .entry = j_arp_process,  
  44. .kp.symbol_name = "arp_process" 
  45. };  
  46.  
  47. static struct jprobe my_jp2 = {  
  48. .entry = j_fib_validate_source,  
  49. .kp.symbol_name = "fib_validate_source" 
  50. };  
  51.  
  52. static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)  
  53. {  
  54. printk("Calling: %s()\n", ri->rp->kp.symbol_name);  
  55. return(0);  
  56. };  
  57.  
  58. static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)  
  59. {  
  60. int eax;  
  61.  
  62. eax = regs->ax & 0xffff ;  
  63. printk("Returning: %s() with a return value: 0x%lx(64bit) 0x%x(32bit)\n", ri->rp->kp.symbol_name, regs->ax, eax);  
  64.  
  65. return(0);  
  66. };  
  67.  
  68. static int fib_lookup_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)  
  69. {  
  70. struct fib_result *resp;  
  71.  
  72. resp = (struct fib_result *) regs->dx;  
  73. printk("Calling: %s()\n", ri->rp->kp.symbol_name);  
  74. *((struct fib_result **)ri->data) = resp;  
  75.  
  76. return(0);  
  77. };  
  78.  
  79. static int fib_lookup_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)  
  80. {  
  81. struct fib_result *resp;  
  82. int eax;  
  83.  
  84. eax = regs->ax & 0xffff ;  
  85. resp = *((struct fib_result **) ri->data);  
  86. printk("Returning: fib_lookup() with a return value: 0x%lx(64bit) 0x%x(32bit), result->type: %d\n", regs->ax, eax, resp->type);  
  87.  
  88. return(0);  
  89. }  
  90.  
  91. static struct kretprobe my_rp1 = {  
  92. .handler = return_handler,  
  93. .entry_handler = entry_handler,  
  94. .kp.symbol_name = "ip_route_input_slow" 
  95. };  
  96.  
  97. static struct kretprobe my_rp2 = {  
  98. .handler = return_handler,  
  99. .entry_handler = entry_handler,  
  100. .kp.symbol_name = "fib_validate_source" 
  101. };  
  102.  
  103. static struct kretprobe my_rp3 = {  
  104. .handler = fib_lookup_return_handler,  
  105. .entry_handler = fib_lookup_entry_handler,  
  106. .kp.symbol_name = "fib_lookup",  
  107. .data_size = sizeof(struct fib_result *)  
  108. };  
  109.  
  110. static int __init init_myprobe(void)  
  111. {  
  112. int ret;  
  113.  
  114. printk("RTN_UNICAST is %d\n", RTN_UNICAST);  
  115. if ( (ret = register_jprobe(&my_jp1)) < 0) {  
  116. printk("register_jprobe %s failed, returned %d\n", my_jp1.kp.symbol_name, ret);  
  117. return(-1);  
  118. }  
  119.  
  120. if ( (ret = register_jprobe(&my_jp2)) < 0) {  
  121. printk("register_jprobe %s failed, returned %d\n", my_jp2.kp.symbol_name, ret);  
  122. return(-1);  
  123. }  
  124.  
  125. if ( (ret = register_kretprobe(&my_rp1)) < 0 ) {  
  126. printk("register_kretprobe %s failed, returned %d\n", my_rp1.kp.symbol_name, ret);  
  127. unregister_jprobe(&my_jp1);  
  128. unregister_jprobe(&my_jp2);  
  129. return(-1);  
  130. }  
  131.  
  132. if ( (ret = register_kretprobe(&my_rp2)) < 0 ) {  
  133. printk("register_kretprobe %s failed, returned %d\n", my_rp2.kp.symbol_name, ret);  
  134. unregister_jprobe(&my_jp1);  
  135. unregister_jprobe(&my_jp2);  
  136. unregister_kretprobe(&my_rp1);  
  137. return(-1);  
  138. }  
  139.  
  140. if ( (ret = register_kretprobe(&my_rp3)) < 0 ) {  
  141. printk("register_kretprobe %s failed, returned %d\n", my_rp3.kp.symbol_name, ret);  
  142. unregister_jprobe(&my_jp1);  
  143. unregister_jprobe(&my_jp2);  
  144. unregister_kretprobe(&my_rp1);  
  145. unregister_kretprobe(&my_rp2);  
  146. return(-1);  
  147. }  
  148.  
  149. return 0;  
  150. }  
  151.  
  152.  
  153. static void __exit rel_myprobe(void)  
  154. {  
  155. unregister_jprobe(&my_jp1);  
  156. unregister_jprobe(&my_jp2);  
  157. unregister_kretprobe(&my_rp1);  
  158. unregister_kretprobe(&my_rp2);  
  159. unregister_kretprobe(&my_rp3);  
  160. }  
  161.  
  162. module_init(init_myprobe);  
  163. module_exit(rel_myprobe);  
  164.  
  165. Makefile obj-m += arp_probe.o  
  166. Making #> make -C /usr/src/kernels/2.6.32-71.el6.x86_64/ M=`pwd` modules 

Linux故障定位技術(shù)詳解與實例的內(nèi)容介紹完了,希望通過本文紅帽Linux故障定位技術(shù)的學習能對你有所幫助!

原文地址:http://beareyes.com.cn/2/lib/201109/27/20110927182_0.htm

責任編輯:程站 來源: BEAREYES.COM
相關(guān)推薦

2013-07-25 14:50:03

2009-09-10 18:55:07

2010-08-17 15:09:45

綜合布線系統(tǒng)故障

2014-04-24 10:14:32

紅帽

2023-01-05 07:54:49

vivo故障定位

2009-02-09 10:40:00

通信光纜故障維修

2023-07-07 10:37:43

自動駕駛技術(shù)

2010-09-13 13:12:57

CSS定位

2010-06-22 10:28:04

linux at命令

2010-09-10 13:07:51

CSS DIV絕對定位CSS DIV固定定位

2023-06-14 08:49:22

PodKubernetes

2017-08-28 14:43:28

Kubernetes技術(shù)紅帽

2010-06-24 16:55:47

Linux chgrp

2010-06-18 10:33:03

Linux Acces

2018-02-07 09:25:50

Linux命令touch

2010-04-22 18:09:38

Aix系統(tǒng)

2018-07-04 10:21:21

2012-11-02 10:49:23

紅帽OpenShift

2009-12-25 10:31:31

Linux網(wǎng)絡(luò)故障

2009-09-03 15:39:15

紅帽集成虛擬化RHEL Linux
點贊
收藏

51CTO技術(shù)棧公眾號

国产精品国产精品国产专区| 黄色激情小视频| 日韩久久一区二区三区| 国产欧美一区二区精品久导航| 国产精品一区二区3区| 麻豆视频在线免费看| 婷婷激情久久| 91精品国产免费| 99999精品视频| 在线观看wwwxxxx| 久久婷婷国产综合精品青草| 国产综合色香蕉精品| 伊人久久综合视频| 久久久久亚洲| 亚洲人在线观看| 性活交片大全免费看| 99久久亚洲国产日韩美女| 亚洲线精品一区二区三区| 日韩精品大片| 午夜视频免费在线| 国产剧情一区在线| 国产日本欧美一区二区三区在线| 亚洲 欧美 视频| 欧美国产专区| 精品国产一区二区三区久久狼5月| 艳妇乳肉亭妇荡乳av| 久久gogo国模啪啪裸体| 91福利小视频| 欧美视频第一区| 538在线视频| 亚洲女子a中天字幕| 亚洲成人第一| 久久天堂电影| 久久综合色一综合色88| 国产经品一区二区| 国产三级伦理片| 麻豆精品一区二区三区| 日本免费久久高清视频| 欧美日韩乱国产| 伊人成人在线视频| 欧美日韩电影在线观看| www.av成人| 天天射成人网| 精品国内产的精品视频在线观看| 中文字幕av久久爽一区| 国产区精品区| 国产亚洲精品美女久久久| 一级性生活毛片| 最新国产一区| 亚洲人成电影网站色…| 国产又粗又猛又爽视频| 亚洲色图美女| 亚洲欧洲视频在线| 91视频免费观看网站| 亚洲性视频大全| 精品网站999www| 国产精品伦子伦| 网曝91综合精品门事件在线| 日韩国产精品一区| 加勒比一区二区| 国产亚洲电影| 中文字幕九色91在线| 免费黄色片网站| 成人情趣视频网站| 久久精品视频在线播放| 午夜国产福利一区二区| 欧美日本不卡高清| 韩国v欧美v日本v亚洲| 国产成人自拍视频在线| 日韩精品亚洲专区| 成人免费xxxxx在线观看| 国产欧美日韩成人| 波多野结衣视频一区| 久久精品ww人人做人人爽| 欧美日韩在线精品一区二区三区激情综| www国产精品av| 午夜精品短视频| 久久77777| 午夜久久电影网| 日韩中文字幕组| 成人在线分类| 日韩成人中文电影| 精品少妇一区二区三区密爱| 欧美精品国产一区二区| 国产+成+人+亚洲欧洲| www.色国产| 久88久久88久久久| 国产伦理久久久| 国产对白叫床清晰在线播放| 亚洲精品ww久久久久久p站| 久久国产亚洲精品无码| 精品乱码一区二区三区四区| 精品国产自在久精品国产| 亚洲第一黄色网址| 国产精品久久久久久久免费观看 | 六月婷婷综合| 制服.丝袜.亚洲.中文.综合| 特大黑人巨人吊xxxx| 亚洲成av人片乱码色午夜| 午夜精品一区二区三区av| 在线观看视频二区| 91亚洲精华国产精华精华液| 亚洲人成77777| 男人的天堂免费在线视频| 欧美区在线观看| 青青草视频成人| 亚洲精品成人无限看| 日韩美女av在线免费观看| www.国产.com| 国产精品伦理一区二区| 亚洲中文字幕无码中文字| 国产精品美女久久久久| 中国日韩欧美久久久久久久久| 日本熟妇毛耸耸xxxxxx| 国产综合色精品一区二区三区| 欧美日韩综合另类| bl在线肉h视频大尺度| 91麻豆精品91久久久久久清纯 | 97免费中文视频在线观看| 国产女18毛片多18精品| 国产精品无遮挡| 国产精品-区区久久久狼 | 欧美一级片免费观看| 欧美男男video| 3atv一区二区三区| 免费黄色国产视频| 麻豆91在线播放免费| 日本成人黄色| 一区二区三区电影大全| 亚洲精品一区二区三区精华液 | 欧美日韩xx| 欧美日韩综合不卡| 91导航在线观看| 日韩avvvv在线播放| 蜜桃日韩视频| a一区二区三区| 日韩精品免费一线在线观看| 久久久美女视频| 国产91精品免费| 国产小视频免费| 丁香综合av| 国内精品视频在线| 五月婷婷狠狠干| 五月激情综合网| 好吊一区二区三区视频| 国产精品毛片在线| 欧美精品成人一区二区在线观看| 国产资源在线观看入口av| 亚洲成人xxx| 国产精品黄色大片| 久久人人爽人人爽| 午夜欧美福利视频| 北条麻妃国产九九九精品小说 | 久久影视电视剧免费网站清宫辞电视 | 99久久夜色精品国产亚洲1000部| 国产区精品视频| 哥也色在线视频| 欧美xxxxx牲另类人与| 精品视频在线观看免费| 99久久久久久99| 国产精品人人妻人人爽人人牛| 国产一区二区三区四区五区传媒| 国产精品极品美女在线观看免费 | 亚洲91精品在线观看| 天天干免费视频| 91豆麻精品91久久久久久| 貂蝉被到爽流白浆在线观看| 国产一区二区h| 欧美精品自拍视频| 国产欧美日韩精品高清二区综合区| 国产精品视频不卡| 在线看福利影| 亚洲国产精品悠悠久久琪琪| 亚洲高清视频免费观看| 亚洲色图欧美偷拍| 亚洲无人区码一码二码三码| 噜噜噜久久亚洲精品国产品小说| 亚洲精品自在在线观看| 超碰在线成人| 国产成人精品在线播放| 免费黄色在线| 亚洲国产精品一区二区三区| 午夜视频网站在线观看| 夜夜亚洲天天久久| 免费观看a级片| 国产成人自拍高清视频在线免费播放| h无码动漫在线观看| 成人91在线| 国产精品v欧美精品v日韩精品| 欧美日韩电影免费看| 欧美精品在线免费| 欧美女子与性| 日韩欧美在线影院| 国产黄网在线观看| 亚洲一区二区三区四区五区中文| av男人的天堂av| 国产精品69毛片高清亚洲| 日韩在线xxx| 欧美日韩天堂| 亚洲永久激情精品| 婷婷亚洲成人| 国产欧美一区二区三区另类精品| 岛国一区二区| 国产91精品最新在线播放| 日本天码aⅴ片在线电影网站| 国产一区二区动漫| 天天在线女人的天堂视频| 91精品视频网| 艳妇乳肉豪妇荡乳av无码福利| 亚洲一区在线免费观看| www.黄色com| 国产日韩欧美电影| 国产制服丝袜在线| 成人av资源站| 中文字幕1区2区| 免费在线一区观看| 日韩免费高清在线| 国产日韩欧美三级| 妞干网在线视频观看| 欧美在线高清| 中文字幕乱码一区二区三区 | 国产亚洲欧洲在线| 视频三区在线观看| 日韩成人网免费视频| 日韩一级片免费| 精品日韩一区二区三区免费视频| 91亚洲欧美激情| 欧美日韩黄色一区二区| 国产在线一级片| 在线观看免费视频综合| 精品人妻无码一区二区性色| 黄色一区二区三区| 日韩乱码一区二区| 精品欧美aⅴ在线网站| 国产无遮挡又黄又爽又色| 亚洲综合av网| 久久久久久久久久91| 亚洲自拍与偷拍| 国产在线拍揄自揄拍无码视频| 一区二区三区精品久久久| 欧美成人一二三区| 亚洲综合色自拍一区| 久青草视频在线观看| 亚洲一区二区三区爽爽爽爽爽| 九九热只有精品| 亚洲五码中文字幕| 日韩精品视频免费播放| 亚洲成a天堂v人片| 日韩免费不卡视频| 亚洲v日本v欧美v久久精品| 日本在线免费观看| 色婷婷综合久久久久中文| 亚洲乱码国产乱码精品| 欧美亚洲一区二区在线观看| 中文字幕一区二区人妻痴汉电车| 欧美日韩精品一区二区| 黄色一区二区视频| 欧美视频第二页| 国产精品久久久久久久免费看| 欧美一级一级性生活免费录像| 精品人妻少妇嫩草av无码专区| 精品国产三级电影在线观看| 天天综合天天色| 亚洲欧美激情一区| 麻豆电影在线播放| 欧美精品videossex88| 日韩理论视频| 国产精品久久二区| 警花av一区二区三区| 久久久一本精品99久久精品| 欧美手机在线| 97久久国产亚洲精品超碰热| 国产亚洲一区在线| 少妇一级淫免费播放| 粉嫩av一区二区三区| 9.1成人看片免费版| 国产精品不卡在线| 国产精彩视频在线| 欧美在线你懂得| 欧美熟女一区二区| 国产亚洲精品久久久优势 | 一区二区三区在线观看动漫| 日本一本高清视频| 欧美日韩精品三区| 四季av日韩精品一区| 中文字幕日韩在线播放| 爱情岛亚洲播放路线| 国产精品国产亚洲伊人久久| 一区二区三区视频播放| 日本不卡在线播放| 亚洲高清av| 九九久久久久久| 久久综合成人精品亚洲另类欧美| 免费中文字幕日韩| 欧美午夜激情在线| 精品国产av鲁一鲁一区| 亚洲欧美日韩视频一区| 欧美videossex| 国产日韩av在线| 免费欧美一区| 丁香六月激情婷婷| 狠狠色狠狠色合久久伊人| 精品夜夜澡人妻无码av| 亚洲伦理在线精品| 国产裸体美女永久免费无遮挡| 亚洲成人av片| 巨大荫蒂视频欧美大片| 国产精品成av人在线视午夜片| 成人高潮视频| 亚洲小说欧美另类激情| 日韩影院免费视频| 中文字幕高清视频| 婷婷久久综合九色综合伊人色| 国产91视频在线| 久久精品成人一区二区三区| 成人午夜精品| 欧美国产视频在线观看| 亚洲欧洲一区| 国产成人精品一区二区三区在线观看 | 欧美日韩一区高清| 国产一级在线观看| 2024亚洲男人天堂| 免费成人三级| 国产午夜大地久久| 成人h版在线观看| 国产一级二级三级视频| 日韩一级高清毛片| 18加网站在线| 亚洲自拍偷拍区| 999精品视频| 美女在线视频一区二区| 亚洲国产精品精华液2区45| 无码人妻精品一区二区三区9厂| 日韩av中文字幕在线免费观看| 国内高清免费在线视频| 官网99热精品| 一区在线视频观看| 欧洲一级黄色片| 色呦呦日韩精品| 黄色免费在线播放| 国产成人久久久精品一区| 久久av超碰| 日日噜噜噜噜久久久精品毛片| 久久久99精品免费观看不卡| 色老头一区二区| 在线日韩中文字幕| 欧洲亚洲精品久久久久| 伊人久久青草| 国产剧情一区二区| 国产真实夫妇交换视频| 亚洲国产日韩欧美在线99| 天堂中文av在线资源库| 日韩精品欧美专区| 六月丁香综合在线视频| 成人免费视频国产免费观看| 日韩精品一区在线| 蜜桃av在线| 天堂资源在线亚洲资源| 国内精品不卡在线| 久久久久亚洲AV| 亚洲欧美日韩天堂一区二区| 国产成人精品一区二区三区在线| 不卡中文字幕在线| 岛国精品在线播放| 欧美一区二区三区网站| 中文字幕欧美日韩| 99精品在免费线中文字幕网站一区| 日本中文字幕网址| 欧美韩国日本不卡| 午夜精品一二三区| 97在线视频精品| 青青草成人影院| 久久久久久久久久影视| 色综合久久综合中文综合网| 蜜桃av在线免费观看| 国产视频99| 激情六月婷婷综合| 日本少妇裸体做爰| 日韩中文字幕免费看| 国产精品欧美大片| 日本888xxxx| 亚洲va国产天堂va久久en| 国产午夜在线视频| av激情久久| 美女免费视频一区二区| 久久免费公开视频| 在线播放国产精品| www.亚洲一二| 欧美三级理论片| 亚洲mv在线观看| 午夜免费福利在线观看| 精品免费国产| 国产精品亚洲一区二区三区在线 | 国产一区不卡精品| 国产精品一区无码| 欧美国产日韩xxxxx| 欧美一区二区三区高清视频| 久久久高清视频| 欧美精品久久久久久久久老牛影院| 蜜桃在线视频|