LINUX核心設計與實現之除錯

2021-06-19 02:53:07 字數 3768 閱讀 9311

核心排程主要靠經驗和對整個作業系統的把握.

18.1 排程前需要準備什麼

重現bug.

18.2 核心中的

bug

引發核心中的bug

的原因如下:

.同步;

.定時限制;

.競爭條件.

18.3 printk()

在終端沒有初始化之前,printk()

函式是不可用的

.比如在

setup_arch()

函式之前

.不過可以用

printk()

函式的變體

--early_printk().

不過此函式和平台息息相關.

printk()函式的等級記錄.如

: printk(kern_debug "this is a debug notice!\n");

核心用這個指定的記錄等級和當前終端等級console_loglevel

來決定是不是向終端上列印

.如果比當前終端等級

console_loglevel

數值小,

則列印輸出

.預設等級為

default_message_loglevel.

各等級如下表所示:

自上而下依次值為<0>

到<7>.

等級記錄(loglevel)

定義在檔案.

核心訊息都被儲存在乙個log_buf_len

大小的環形佇列中

.該緩衝區大小可以編譯時通過

config_log_buf_shift

進行調整

.單處理器上預設是

16kb.

核心訊息的實現方式:

標準的linux

系統中,

使用者空間的守護程序

klogd從記錄緩衝區中獲取核心訊息.

再通過syslogd守護程序將它們儲存在系統日誌檔案中.klogd

程式即可以從

/proc/kmsg

檔案中也可以通過

syslog()

系統呼叫讀取這些訊息.

syslogd守護程序負責把它接收到的所有訊息加進乙個檔案中

,該檔案預設是

/var/log/messages,

可以通過

/etc/syslog.conf

配置檔案重新指定;

klogd守護程序負責讀取核心訊息.

18.4 oops

核心異常表現謂之oops.

下面以乙個例項進行解說乙個

oops

的意義:

紅色框是出現oops暫存器的值

.一般來說

,我們可以通過檢視哪個暫存器包含了

null(

乙個所有位都為零的數值

)進而找出是函式的哪個變數的值不正常.

藍色框是出現oops

函式回溯棧

.往往這些資訊我們更需要

.如藍色框部分提供給我們的資訊如下:

機器處於空閒狀態,

正在進行執行

idle迴圈,

由cpu_idle()

反覆呼叫

default_idle().

此時定時器產生中斷了

,它引起了對定時器的處理

.tulip_timer()

這個定時器處理函式被呼叫

,而就是它引用了空指標

.我們甚至通過偏移量(像

0x128/0x1c4

這些出現在函式左側的數字

)找出導致問題的語句.

18.5 核心除錯配置選項

在編譯的時候,

為了方便除錯和測試**

,核心提供了許多配置選項

.這些選項都在核心配置編輯器的核心開發

(kernel hacking)

選單項中

,它們都依賴於

config_debug_kernel.

主要排程選項如下:

slab layer debugging(slab層除錯選項);

high-memory debugging(高階記憶體除錯選項);

i/o mamping debugging(i/o對映除錯選項);

spin-lock debugging(自旋鎖除錯選項);

stack-overflow checking(棧溢位檢查選項);

sleep-inside-spinlock checking(自旋鎖內睡眠選項);

排程原子操作

如果原子操作**裡面呼叫了可能引起睡眠的**的話,

後果將不堪設想.因此

,核心提供了乙個原子操作計數器

.它可以被配置成一旦在原子操作過程中程序進入睡眠或做了一些可能引起睡眠的操作

,就列印警告資訊並提供追蹤線索

.下面的這些選項可以最大限度地利用該特性:

config_preempt=y

config_debug_kernel=y

config_kallsyms=y

config_spinlock_sleep=y

18.6 引發

bug並列印資訊

一些核心呼叫可以用來方便標記bug,

提供斷言並輸出資訊

.最常用的兩個是

bug()

和bug_on().

當被呼叫的時候,

它們會引發

oops,

導致棧回溯和錯誤資訊的列印

.panic()的呼叫可以引發更嚴重的錯誤

.此函式不但會列印錯誤訊息

,還會掛起整個系統.

18.8 核心排程器

常用的核心排程器主要有gdb

、kgdb

和kdb.

18.9 核心排程的常用手段

1).用

uid作為選擇條件

一般情況下,

我們在重新封裝了核心一些功能函式的時候

,要保留原來的功能函式

.滿足一定的條件就去執行我們編寫的功能函式.如下

2).使用條件變數

實現思想和上述類似,

用條件變數選擇其中一分支執行我們重新封裝的函式.

3).使用統計變數

主要統計核心裡面某些事件的規律.

4).限制重複頻率

如果我們不加限制在核心中新增printk()函式,

或者某個被頻繁呼叫的函式裡面代入了

printk()函式.

螢幕往往布滿列印資訊.因此

,我們需要作一定的限制

.示意**如下:

sttic unsigned long prev_jiffy = jiffies;

if(time_after(jiffies,prev_jiffy + 2 * hz))

prev_jiffy = jiffies;

printk(kern_err "blah blah blah\n");

18.10 核心

bug

在實際開發中,

往往某個版本存在某種

bug現象

,而舊版本不會

,可通過比較相關**找出問題癥結所在.

linux 核心設計與實現相關

有待繼續補充。第一章 linux核心簡介 需要注意 核心開發其實並不難。第二章 從核心出發 核心開發需要注意 1 沒有c庫,c庫太大了 2 沒有記憶體保護機制 3 不要輕易使用浮點數 4 可移植的重要性 5 同步和併發 疑問 編譯和安裝核心?必須在linux下麼?其他機器安裝了gcc編譯器呢?能否編...

Linux核心設計與實現總結。

1.程序管理。本章主要是介紹程序的乙個靜態的狀態,包括系統如何組織程序。建立,啟動,到最後死亡的乙個概念性認識,沒有更加深刻的知識。2.程序排程。本章比較重要。1.搶占式排程策略。2.倆程序間上下文切換 有倆函式 switch mm 和 switch to倆函式完成此功能。具體細節需要閱讀其他書籍 ...

linux核心設計與實現 前言

認真閱讀原始碼很重要,應該鑽研並嘗試著手改一些 尋找乙個bug然後去修改它,改進你的硬體裝置的驅動程式 unix特點 作業系統 指系統中負責完成最基本功能和系統管理的部分。包括 核心 裝置驅動程式 啟動引導程式 命令列shell或其他種類的使用者介面 基本的檔案管理和系統工具。核心組成 中斷服務程式...