linux 內核warn_on/Bug_on

1,warn_on()?

warn_on()?是 Linux 內核中用于報告潛在問題或警告的宏。與?bug_on()?不同,bug_on()?通常用于報告嚴重錯誤,其觸發往往會導致內核Oops或panic,而?warn_on()?則用于報告不太嚴重的、可能只是潛在問題或預期外情況的情況。它的觸發通常不會立即導致系統崩潰,而是記錄警告信息并打印 call trace,讓開發者或管理員了解發生了什么。

warn_on()?的工作原理(簡化版):

  1. 條件判斷warn_on(condition)?宏會被展開為類似?if (unlikely(condition))?的代碼。

  2. 觸發警告:如果?condition?為真,代碼會執行到一個內核函數,通常是?WARN_ON()?宏或相關的函數(如?printk()?加上特定的格式和調試信息)。

  3. 打印信息:這個函數會打印出警告信息,包括:觸發警告的文件名和行號。內核版本信息。Call Trace: 顯示觸發警告的函數調用鏈。這是?warn_on()?提供的最有價值的信息之一。其他可能的調試信息(如寄存器狀態,取決于內核配置)。

  4. 繼續執行:與?bug_on()?不同,warn_on()?通常會打印信息后繼續執行下一條指令。這允許系統在記錄問題后嘗試從警告狀態恢復(盡管有時警告也預示著嚴重問題)。

舉例:

#include <linux/kernel.h>
#include <linux/module.h>void my_driver_function(struct my_data *data) {// ... 一些代碼 ...// 檢查指針是否為 NULL,如果是則發出警告WARN_ON(!data); // 在 my_driver.c:100// ... 更多代碼 ...
}static int __init my_driver_init(void) {// ... 初始化代碼 ...my_driver_function(NULL); // 故意傳遞 NULL 來觸發警告// ... 更多初始化代碼 ...return 0;
}static void __exit my_driver_exit(void) {// ... 清理代碼 ...
}module_init(my_driver_init);
module_exit(my_driver_exit);

當?my_driver_function(NULL)?被調用時,WARN_ON(!data)?的條件為真(因為?data?是 NULL),就會觸發警告。

假設這個警告發生在 CPU 0 上,內核環緩沖區 (dmesg) 中可能會看到類似如下的輸出(具體格式可能因內核版本和配置略有不同):

[ 123.456789] WARNING: CPU: 0 PID: 1234 at drivers/my_driver/my_driver.c:100 my_driver_function+0x5a/0x120 (not tainted)

[ 123.456789] Hardware name: ...

[ 123.456789] Call Trace:

[ 123.456789] dump_stack+0x4c/0x73

[ 123.456789] ? my_driver_function+0x5a/0x120

[ 123.456789] ? WARN_ON+0x7b/0x90

[ 123.456789] my_driver_function+0x5a/0x120 [my_driver]

[ 123.456789] my_driver_init+0x40/0x100 [my_driver]

[ 123.456789] do_one_initcall+0x130/0x170

[ 123.456789] kernel_init_freeable+0x130/0x170

[ 123.456789] ? kernel_init+0x10/0x10

[ 123.456789] kernel_init+0x10/0x170

[ 123.456789] ret_from_fork+0x22/0x30

[ 123.456789] ---[ end trace 123456789abcdef ]---

2,bug_on()

bug_on()?觸發時如何打印 call trace(調用跟蹤)。

bug_on()?是 Linux 內核中用于檢測和報告嚴重錯誤的宏。它的作用類似于 C 語言中的?assert(), 但專門用于內核環境。當傳遞給?bug_on()?的條件為真(非零)時,它會觸發一個內核 Oops(類似于用戶空間的段錯誤),并打印出非常有用的調試信息,其中就包括 call trace。

bug_on()?的工作原理(簡化版):

  1. 條件判斷bug_on(condition)?宏會被展開為類似?if (unlikely(condition)) { ... }?的代碼。
  2. 觸發錯誤:如果?condition?為真,代碼會執行到一個內核函數,通常是?BUG()?或相關的宏/函數。
  3. 打印信息:這個函數會打印出錯誤信息,包括:
    • 觸發?BUG?的文件名和行號。
    • 內核版本信息。
    • Call Trace: 這是最關鍵的部分,它顯示了觸發?BUG?的函數調用鏈。
    • CPU 信息、寄存器狀態等(取決于內核配置和 Oops 類型)。
  4. 處理后果:通常會導致進程終止(如果是進程中的錯誤)或系統進入 Oops 狀態,可能需要手動重啟。在啟用?CONFIG_PANIC_ON_OOPS=y?的情況下,可能會直接觸發?panic()?導致系統崩潰。
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/printk.h> // for pr_info// 假設這個函數不應該被調用
static void do_something_undefined(void)
{// 觸發 bug_on: 假設某個不應該為真的條件發生了// 這里我們強制讓它為真來演示int should_be_false = 1;// 當 should_be_false 為真時,bug_on 會觸發// 內核宏通常寫成 bug_on(should_be_false)// 為了演示,我們假設它觸發了// --- 以下是模擬的 bug_on 觸發后的內核輸出 ---// 文件: my_module.c// 函數: do_something_undefined// 行號: 15// --- 內核實際打印信息 ---// BUG: Badness at my_module.c:15 in do_something_undefined()// Modules linked in: my_module// Pid: 1234, comm: insmod Tainted: G ? ? ? ?W ...// RIP: 0010:[do_something_undefined+0x10/0x30]// Code: Bad RIP value.// RSP: 0000:ffffc900003aefb8 EFLAGS: 00010206// RAX: 0 RAX: 0 RAX: 0 RAX: 0// ...// Call Trace:// ?my_function+0x20/0x50 [my_module]// ?another_function+0x15/0x40 [my_module]// ?my_init+0x25/0x80 [my_module]// ?do_one_initcall+0x80/0x300// ?kernel_init_freeable+0x130/0x170// ?? kthreadd+0x70/0x70// ?kernel_init+0x10/0x100// ?ret_from_fork+0x22/0x30// --- 內核實際打印信息結束 ---pr_info("This line won't be reached if bug_on triggers.\n");
}static int my_function(void)
{pr_info("Inside my_function\n");do_something_undefined(); // 調用那個會觸發 bug_on 的函數return 0;
}static int another_function(void)
{pr_info("Inside another_function\n");return my_function(); // 調用 my_function
}static int __init my_init(void)
{pr_info("Initializing my module\n");return another_function(); // 調用 another_function
}static void __exit my_exit(void)
{pr_info("Exiting my module\n");
}module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A module demonstrating bug_on call trace");

異常打印如下:?

BUG: Badness at my_module.c:15 in do_something_undefined()
Modules linked in: my_module
...
Pid: [PID], comm: [Command that loaded the module, e.g., insmod]
RIP: [Instruction pointer at the bug_on location]
Code: [Opcode at RIP]
RSP: [Stack pointer]
...
Call Trace:
?do_something_undefined+0x10/0x30 [my_module]
?my_function+0x20/0x50 [my_module]
?another_function+0x15/0x40 [my_module]
?my_init+0x25/0x80 [my_module]
?do_one_initcall+0x80/0x300
?kernel_init_freeable+0x130/0x170
?? kthreadd+0x70/0x70
?kernel_init+0x10/0x100
?ret_from_fork+0x22/0x30

如何獲取?bug_on?的輸出

  1. 串口 (Serial Console): 如果你的系統通過串口連接,錯誤信息通常會直接輸出到串口。
  2. tty 控制臺: 如果?bug_on?發生在直接連接的顯示器上,信息會打印在那里。
  3. dmesg?命令: 在?bug_on?發生后,即使系統可能已經掛起或重啟,你通常也可以使用?dmesg?命令來查看內核環緩沖區(kernel ring buffer)中的消息,包括 Oops 信息和 Call Trace。
  4. /var/log/kern.log?或?/var/log/syslog: 在某些系統上,kern.log?或?syslog?文件會記錄內核消息,包括 Oops。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/84830.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/84830.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/84830.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SQL輸出20個9

在SQL Server中要輸出20個連續的9&#xff0c;可以使用以下幾種方法&#xff1a; 使用REPLICATE函數重復生成字符&#xff1a; SELECT REPLICATE(9, 20) AS Result 2. 使用UNION ALL聯合查詢生成多行&#xff1a; SELECT 9 AS Number FROM (VALUES (1),(1),(1),(1),(1),(1),…

懶人云電腦方案:飛牛NAS遠程喚醒 + 節點小寶一鍵喚醒、遠程控制Windows!

后臺高頻問題解答&#xff1a; “博主&#xff0c;飛牛NAS能定時開關機了&#xff0c;能不能讓它順便把家里Windows電腦也遠程喚醒控制&#xff1f;最好點一下就能連&#xff0c;不用記IP端口那種&#xff01;” 安排&#xff01;今天這套方案完美實現&#xff1a; ? 飛牛NAS…

Linux特殊符號

1 管道符| 管道符號 | 用于將一個命令的輸出作為另一個命令的輸入。這種機制允許將多個命令組合在一起&#xff0c;形成一個數據處理鏈&#xff0c;每個命令處理前一個命令的輸出&#xff0c;從而實現復雜的數據處理任務。示例 # 查詢/var/log目錄下所有的log文件,并進行分頁…

初識Docker:容器化技術的入門指南

初識Docker&#xff1a;容器化技術的入門指南 一、Docker是什么&#xff1a;容器化技術的核心概念二、Docker的核心優勢2.1 環境一致性2.2 高效部署與快速迭代2.3 資源利用率高 三、Docker的安裝與基本使用3.1 安裝Docker3.2 Docker基本概念3.3 第一個Docker容器體驗 四、Docke…

商務風企業公司推廣培訓計劃PPT模版分享

商務風企業公司推廣培訓計劃PPT模版分享&#xff1a;商務培訓推廣計劃PPT模版https://pan.quark.cn/s/063282eaf739 第1套PPT模版&#xff0c;綠橙配色&#xff0c;幾何圖形拼接背景&#xff0c;有中英文標題和占位文本。 第2套PPT模版是黑金高端商務風格&#xff0c;有匯報人…

深入理解Nginx:詳盡配置手冊

Nginx是一款高性能的HTTP和反向代理服務器&#xff0c;廣泛應用于負載均衡、緩存和Web服務器等場景。隨著互聯網應用的快速發展&#xff0c;掌握Nginx的配置和優化技巧顯得尤為重要。在本篇文章中&#xff0c;我們將深入探討Nginx的配置&#xff0c;幫助你更好地理解和使用這款…

每日leetcode

1572. 矩陣對角線元素的和 - 力扣&#xff08;LeetCode&#xff09; 題目 給你一個正方形矩陣 mat&#xff0c;請你返回矩陣對角線元素的和。 請你返回在矩陣主對角線上的元素和副對角線上且不在主對角線上元素的和。 示例 1&#xff1a; 輸入&#xff1a;mat [[1,2,3], …

Server 9 ,在 VMware 虛擬機上安裝 Windows 系統完整指南

目錄 前言 一、準備工作 1.1 準備安裝文件 1.2 安裝VMware軟件 1.3 創建新的虛擬機 1.4 開啟虛擬機 二、注意事項 2.1 調整硬件設置 2.2 啟動順序配置 2.3 固件類型選擇 2.4 安全啟動配置 三、安裝優化 3.1 安裝VMware Tools 3.2 系統更新與激活 四、更多操作 ?…

最終章:終焉之塔 · 前端之道

第一章&#xff1a;HTML基石現實的骨架 第二章&#xff1a;CSS秘典 色彩與布局的力量 第三章&#xff1a;JavaScript引擎 行為之火 第四章&#xff1a;DOM迷宮 掌控頁面之心 第五章&#xff1a;異步幻境 時間與數據的秘密 第六章&#xff1a;事件風暴 用戶的意志 第七章&a…

詳解 .net9 內置 Lock 對象,更加現代化和靈活可控的鎖對象

.NET 9 引入了全新的 System.Threading.Lock 類型&#xff0c;作為更現代、類型安全且具備遞歸支持的同步原語。與傳統的基于 Monitor.Enter/lock(obj) 的方式不同&#xff0c;Lock 是一個具體的類&#xff0c;提供了更靈活的 API 和結構化編程模型。 Lock 類 Lock 是一個具體…

python幾行命令實現快速打包apk

1. ??環境準備? sudo apt update sudo apt install -y python3-pip git zip unzip openjdk-17-jdk sudo apt-get install -y autoconf automake libtool pip install kivy buildozer cython2. ??項目配置? 在項目目錄中初始化Buildozer&#xff1a; buildozer init這會…

實時數倉和離線數倉的區別是什么?企業如何選擇合適的數倉架構?

實時數倉和離線數倉的區別是什么&#xff1f;企業如何選擇合適的數倉架構&#xff1f; 時數倉和離線數倉都是數據倉庫的不同類型&#xff0c;用于存儲和管理企業的數據&#xff0c;但它們在數據處理和使用的時間、速度以及用途方面有明顯的區別。 在介紹實時數倉之前&#xf…

Docker Desktop for Windows 系統設置說明文檔

1. 文檔概述 本文檔旨在詳細說明 Docker Desktop for Windows 應用程序中“設置 (Settings)”界面下的所有可配置選項及其子選項。對于每個配置項&#xff0c;我們將提供其功能描述、推薦配置&#xff08;如適用&#xff09;以及相關注意事項&#xff0c;幫助用戶更好地理解和…

精準監測,健康無憂--XC3576H工控主板賦能亞健康檢測儀

在快節奏的現代生活中&#xff0c;亞健康問題逐漸成為困擾人們健康的隱形殺手。疲勞、失眠、免疫力下降等問題頻發&#xff0c;卻往往因難以察覺而延誤調理。智能亞健康檢測儀通過高科技手段&#xff0c;幫助用戶實時了解身體狀況&#xff0c;提前預警潛在健康風險。 其核心功能…

SBT開源構建工具

SBT 的多元定義與核心解釋 SBT&#xff08;Simple Build Tool&#xff09;是專為 Scala 和 Java 項目設計的開源構建工具&#xff0c;基于 Scala 語言開發&#xff0c;提供依賴管理、編譯、測試、打包等全流程支持。其核心特點包括&#xff1a; 核心功能與特性&#xff1a; …

npm run build后將打包文件夾生成zip壓縮包

安裝依賴 npm install archiver --save-dev準備compress.js文件 const fs require(fs); const archiver require(archiver);const sourceDir ./dist; //替換為你的文件夾路徑 const outputZip ./dist.zip;console.log(開始壓縮); const output fs.createWriteStream(ou…

力扣 215 .數組中的第K個最大元素

文章目錄 題目介紹題解 題目介紹 題解 法一&#xff1a;基于快速排序的選擇方法 以中間元素pivot為基準進行排序后&#xff0c;右指針 r 的位置就是最終全部排序好后pivot的位置&#xff0c;然后去左邊或右邊遞歸尋找第k個位置&#xff08;答案&#xff09;的元素。 代碼如下…

CentOS 7.0重置root密碼

文章目錄 版本&#xff1a;CentOS 7.0內核版本&#xff1a;CentOS Linux, with Linux 3.10.0-123.el7.x86_64 服務器重啟后&#xff0c;等待進入上述頁面&#xff0c;按??鍵&#xff0c;中斷正常啟動。在此頁面按E&#xff0c;進入編輯模式 繼續按?&#xff0c;找到linux16…

Linux之高效文本編輯利器 —— vim

目錄 一、vim的基本概念 二、Vim 的三種基本模式 1. 命令模式&#xff08;Command Mode&#xff09; 2. 插入模式&#xff08;Insert Mode&#xff09; 3. 底行模式&#xff08;Last Line Mode&#xff09; 模式切換方法 IDE例子&#xff1a; 三、vim的基本操作 進入vim…

【STM32】HAL庫 之 CAN 開發指南

基于stm32 f407vet6芯片 使用hal庫開發 can 簡單講解一下can的基礎使用 CubeMX配置 這里打開CAN1 并且設置好波特率和NVIC相關的配置 波特率使用波特率計算器軟件 使用采樣率最高的這段 填入 得到波特率1M bit/s 然后編寫代碼 環形緩沖區 #include "driver_buffer.h&qu…