汙點核心¶
當發生一些可能與以後調查問題相關的事情時,核心會將自己標記為“汙點”。不要太擔心這一點,大多數時候執行汙點核心沒有問題;一旦有人想要調查某些問題,這些資訊主要是有意義的,因為它的真正原因可能是導致核心汙點的事件。這就是為什麼來自汙點核心的錯誤報告通常會被開發人員忽略,因此請嘗試用未汙點的核心重現問題。
請注意,即使在您撤消導致汙點的原因(即解除安裝專有核心模組)後,核心仍將保持汙點狀態,以表明核心仍然不可信。這也是為什麼當核心注意到內部問題(“核心錯誤”)、可恢復錯誤(“核心 oops”)或不可恢復錯誤(“核心 panic”)時,會列印汙點狀態並將有關此問題的除錯資訊寫入日誌 dmesg 輸出。也可以透過/proc/中的檔案在執行時檢查汙點狀態。
錯誤、oops或panic訊息中的汙點標誌¶
您可以在以“CPU:”開頭的一行的頂部附近找到汙點狀態;如果在程序ID (“PID:”) 和觸發該事件的命令的縮寫名稱 (“Comm:”) 之後顯示核心被汙點的原因
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
Oops: 0002 [#1] SMP PTI
CPU: 0 PID: 4424 Comm: insmod Tainted: P W O 4.20.0-0.rc6.fc30 #1
Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
RIP: 0010:my_oops_init+0x13/0x1000 [kpanic]
[...]
如果核心在事件發生時未被汙點,您會在此處找到“Not tainted: ”;如果被汙點,則將列印“Tainted: ”以及字母或空格。在上面的例子中,它看起來像這樣
Tainted: P W O
這些字元的含義在下表中進行了解釋。在這種情況下,核心早期被汙染是因為載入了專有模組 (P),發生了警告 (W),並且載入了外部構建的模組 (O)。要解碼其他字母,請使用下表。
在執行時解碼汙點狀態¶
在執行時,您可以透過讀取cat /proc/sys/kernel/tainted來查詢汙點狀態。如果返回0,則核心未被汙點;任何其他數字都表示被汙點的原因。解碼該數字的最簡單方法是指令碼tools/debugging/kernel-chktaint,您的發行版可能會將其作為名為linux-tools或kernel-tools的軟體包的一部分;如果沒有,您可以從git.kernel.org下載該指令碼,並使用sh kernel-chktaint執行它,這將在先前引用的日誌中包含語句的機器上列印如下內容
Kernel is Tainted for following reasons:
* Proprietary module was loaded (#0)
* Kernel issued warning (#9)
* Externally-built ('out-of-tree') module was loaded (#12)
See Documentation/admin-guide/tainted-kernels.rst in the Linux kernel or
https://kernel.linux.club.tw/doc/html/latest/admin-guide/tainted-kernels.html for
a more details explanation of the various taint flags.
Raw taint value as int/string: 4609/'P W O '
您可以嘗試自己解碼該數字。如果只有一種原因導致您的核心被汙點,那麼這很容易,在這種情況下,您可以在下表中找到該數字。如果有多個原因,您需要解碼該數字,因為它是一個位域,其中每個位表示是否存在特定型別的汙點。最好將此留給前面提到的指令碼,但如果您需要快速的東西,可以使用此shell命令來檢查設定了哪些位
$ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done
解碼汙點狀態的表¶
位 |
日誌 |
編號 |
導致核心被汙染的原因 |
|---|---|---|---|
0 |
G/P |
1 |
已載入專有模組 |
1 |
_/F |
2 |
強制載入模組 |
2 |
_/S |
4 |
核心在不符合規範的系統上執行 |
3 |
_/R |
8 |
強制解除安裝模組 |
4 |
_/M |
16 |
處理器報告了機器檢查異常 (MCE) |
5 |
_/B |
32 |
引用了錯誤的頁面或一些意外的頁面標誌 |
6 |
_/U |
64 |
使用者空間應用程式請求汙點 |
7 |
_/D |
128 |
核心最近已死亡,即存在 OOPS 或 BUG |
8 |
_/A |
256 |
ACPI表被使用者覆蓋 |
9 |
_/W |
512 |
核心發出警告 |
10 |
_/C |
1024 |
已載入暫存驅動程式 |
11 |
_/I |
2048 |
應用了針對平臺韌體中錯誤的解決方法 |
12 |
_/O |
4096 |
已載入外部構建(“樹外”)模組 |
13 |
_/E |
8192 |
已載入未簽名的模組 |
14 |
_/L |
16384 |
發生軟鎖死 |
15 |
_/K |
32768 |
核心已進行即時修補 |
16 |
_/X |
65536 |
輔助汙點,為發行版定義和使用 |
17 |
_/T |
131072 |
核心使用結構隨機化外掛構建 |
18 |
_/N |
262144 |
已執行核心測試 |
19 |
_/J |
524288 |
使用者空間在fwctl中使用了改變除錯操作 |
注意:字元_在此表中表示空格,以方便閱讀。
汙點的更詳細說明¶
如果載入的所有模組都具有GPL或相容許可證,則為
G;如果已載入任何專有模組,則為P。沒有MODULE_LICENSE或MODULE_LICENSE未被insmod識別為GPL相容的模組被假定為專有模組。如果任何模組被
insmod -f強制載入,則為F;如果所有模組都正常載入,則為' '。如果核心在不符合規範的處理器或系統上執行,則為
S:硬體已置於不受支援的配置中,因此無法保證正確的執行。例如,如果核心被汙染
在x86上:在不報告PAE但可能具有功能實現的intel CPU(例如Pentium M)上,透過forcepae強制使用PAE,SMP核心在非官方支援SMP的Athlon CPU上執行,MSR正在從使用者空間被探測。
在arm上:核心在某些CPU(例如Keystone 2)上執行,而沒有啟用某些核心功能。
在arm64上:CPU之間的硬體功能不匹配,引導載入程式以不同的模式啟動CPU。
某些驅動程式在不受支援的體系結構上使用(例如,x86_64以外的scsi/snic,非x86/x86_64/itanium上的scsi/ips,為arm64上的irqchip/irq-gic具有損壞的韌體設定......)。
x86/x86_64:微程式碼延遲載入是危險的,會導致核心汙染。它要求所有CPU匯合以確保在系統儘可能靜止時進行更新。但是,更高優先順序的MCE/SMI/NMI可以使控制流遠離該匯合並中斷更新,這對機器可能有害。
如果模組被
rmmod -f強制解除安裝,則為R;如果所有模組都正常解除安裝,則為' '。如果任何處理器報告了機器檢查異常,則為
M;如果未發生機器檢查異常,則為' '。如果頁面釋放函式找到錯誤的頁面引用或一些意外的頁面標誌。這表示硬體問題或核心錯誤;日誌中應該有其他資訊指示發生此汙點的原因。
如果使用者或使用者應用程式專門請求設定Tainted標誌,則為
U;否則為' '。如果核心最近已死亡,即存在OOPS或BUG,則為
D。如果ACPI表已被覆蓋,則為
A。如果核心先前已發出警告,則為
W。(儘管某些警告可能會設定更具體的汙點標誌。)如果已載入暫存驅動程式,則為
C。如果核心正在解決平臺韌體(BIOS或類似韌體)中的嚴重錯誤,則為
I。如果已載入外部構建(“樹外”)模組,則為
O。如果在支援模組簽名的核心中載入了未簽名的模組,則為
E。如果系統先前發生了軟鎖死,則為
L。如果核心已進行即時修補,則為
K。
X輔助汙點,為Linux發行商定義和使用。
T核心使用 randstruct 外掛構建,該外掛可能會有意產生極其不尋常的核心結構佈局(甚至是效能病態的佈局),這在除錯時非常重要。 在構建時設定。
N如果已執行核心測試,例如 KUnit 測試。
J如果使用者空間打開了 /dev/fwctl/* 並執行了 FWTCL_RPC_DEBUG_WRITE 來使用該裝置的除錯功能。 裝置除錯功能可能會導致裝置以未定義的方式發生故障。