内核是Linux系统的“心脏”——一旦它出bug,小则功能异常,大则系统崩溃、死机。但内核bug往往藏在百万行代码中,想快速定位、修复绝非易事。
好在Linux内核官方提供了一份详细的《bug狩猎手册》(kernel.org/doc/html/latest/admin-guide/bug-hunting.html),从识别日志信号到提交修复补丁,全程拆解实用方法。今天我们就基于这份权威文档,梳理一套“内核bug排查实操指南”,帮你高效解决内核故障。
一、先看懂内核的“求救信号”:栈跟踪与Oops信息
当内核遇到bug时,不会“沉默”——它会输出栈跟踪(stack dump)日志,告诉你“哪里出了问题”。这类日志通常分两种场景:
1.常见的“警告型”日志(WARNING)
比如文档中给出的例子,内核会明确标出出错的CPU、进程、代码位置:
------------[cuthere ]------------WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70Modules linkedin: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) ...CPU: 1 PID: 28102 Comm: rmmod Tainted: P WC O 4.8.4-build.1#1Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009...Call Trace: # 函数调用栈,记录bug触发时的代码执行路径[] ? dump_stack+0x44/0x64 [] ? __warn+0xfa/0x120 [] ? module_put+0x57/0x70 # 关键:出错函数及偏移 ...
2.严重的“崩溃型”日志(Oops/BUG)
如果bug导致内核无法继续运行,会输出带“BUG”或“Oops”的日志,比如空指针引用:
BUG: unable to handle kernelNULLpointer dereference at (null)IP: [] iret_exc+ 0x7d0/ 0xa59 # IP=指令指针,指向出错代码地址 Oops:0002[#1] PREEMPT SMP...
3.日志中的“模块标记”要注意
日志里“Modules linked in”后的模块名,会带特殊标记,暗示模块状态:
•(PO):模块处于“待处理”状态(Pending);
•(-):模块正在卸载;
•(+):模块正在加载;
•Tainted: P WC O:内核被“污染”(比如加载了非开源模块,影响调试)。
二、别让关键日志溜走:找到Oops信息的3种场景
想定位bug,首先得拿到完整的Oops日志——内核会把日志存在不同地方,分场景获取:
1.系统还能操作:从常规日志文件拿
内核默认通过klogd把日志传给syslogd,存到这些位置:
•传统系统:/var/log/messages(路径由/etc/syslog.conf配置);
•systemd系统:用journalctl命令查看(比如journalctl -k只看内核日志)。
如果klogd进程意外退出,还能直接读内核缓冲区:
# 把缓冲区日志存到文件dmesg > kernel_bug.log# 或实时读取(按Ctrl+C停止)cat/proc/kmsg > kernel_bug.log
2.系统崩溃卡死:3种“救命”方法
如果机器完全冻住,无法输入命令,试试这3招:
•应急方案:手抄屏幕日志(或拍照),重启后整理。若日志滚屏太快,可重启时加vga=791(高分辨率模式)显示更多内容(需开启vesafb驱动,早期启动阶段的bug无效);
•提前准备:用串口控制台(参考文档Documentation/admin-guide/serial-console.rst)——把两台机器用串口线连接,另一台用Minicom等工具捕获日志,适合长期调试;
•专业方案:开启Kdump(内核崩溃转储)——提前配置后,崩溃时会通过kexec启动备用内核,从内存中提取日志(具体看Documentation/admin-guide/kdump/gdbmacros.txt)。
三、核心步骤:精准定位bug的代码行
拿到Oops日志后,下一步是找到“具体哪行代码出了问题”。文档推荐两种工具,gdb最常用,objdump可备用。
1.首选工具:gdb(需开启调试信息)
gdb能直接把Oops中的内存地址,翻译成“文件名+行号”——但前提是内核编译时开启了**CONFIG_DEBUG_INFO**(调试信息)。
步骤1:开启内核调试信息
在kernel源码目录下,执行命令开启配置:
# 关闭COMPILE_TEST,开启DEBUG_KERNEL和DEBUG_INFO./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO# 重新编译内核(生成带调试信息的vmlinux文件)make vmlinux
步骤2:用gdb定位代码
根据Oops日志中的关键信息(EIP地址或函数偏移),用gdb解析:
•情况1:有EIP地址(比如日志中EIP: 0060:[
gdbvmlinux # 加载带调试信息的内核文件(gdb) l *0xc021e50e # 查看该地址对应的代码
•情况2:有函数偏移(比如日志中EIP is at vt_ioctl+0xda8/0x1482):
gdbvmlinux(gdb) l *vt_ioctl+0xda8 # 查看vt_ioctl函数偏移0xda8的代码# 输出会直接指向文件和行号,比如:# 0x1888 is in vt_ioctl (drivers/tty/vt/vt_ioctl.c:293)
步骤3:模块级定位
如果bug在加载的模块中(比如日志中dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb]),直接加载模块文件解析:
# 加载dvb-usb模块的.o文件gdb drivers/media/usb/dvb-usb/dvb-usb.o(gdb) l *dvb_usb_adapter_frontend_exit+0x3a # 定位模块内代码
2.备用工具:objdump(无调试信息也能用)
如果没开启CONFIG_DEBUG_INFO,或只有模块文件,可用objdump反汇编代码,间接定位问题。
基本用法(查看带源码的反汇编)
# -r:显示重定位信息;-S:混合显示源码和汇编;-l:显示行号objdump -r -S -l net/dccp/ipv4.o
极端情况:无源码时
如果连源码都没有,可提取Oops日志中“Code:”后的字节码,手动反汇编:
1.把Code:后的字节(比如44 24 04 e8 6f ...)存到foo.s文件:
.text.globl foofoo:.byte0x44,0x24,0x04,0xe8,0x6f, ...
1.编译并反汇编:
gcc-c -o foo.o foo.sobjdump --disassemble foo.o # 查看汇编代码,推断逻辑
1.简化操作:用内核自带脚本scripts/decodecode自动处理(支持多架构)。
四、报告bug:让维护者快速接手
定位到bug后,若自己无法修复,需向上游报告——关键是“找对人”,让负责该模块的维护者看到。
1.用脚本找维护者:get_maintainer.pl
内核源码中的scripts/get_maintainer.pl,能直接输出文件的维护者、邮件列表:
# 查看drivers/media/usb/gspca/sonixj.c的维护信息./scripts/get_maintainer.pl --bug -f drivers/media/usb/gspca/sonixj.c
输出结果会包含:
•模块维护者(比如Hans Verkuil
•子系统维护者(比如Mauro Carvalho Chehab
•相关邮件列表(比如linux-media@vger.kernel.org,模块专属列表);
•内核通用列表(linux-kernel@vger.kernel.org)。
2.报告优先级:先bug tracker,再邮件
•若输出中有“bug reporting URIs”(bug跟踪链接),优先在跟踪系统提交;
•若无,发送邮件到“模块专属邮件列表”,并抄送维护者;
•完全没头绪时,直接发linux-kernel@vger.kernel.org(通用列表,覆盖所有维护者)。
五、修复bug:从定位到提交的最后一步
若你有编程能力,可尝试修复bug——提交补丁时,务必先读Documentation/process/submitting-patches.rst,遵守内核代码规范(比如补丁格式、commit信息写法),这能大幅提高补丁被接受的概率。
毕竟开源的核心是协作,你的一个小补丁,可能让成千上万台Linux机器更稳定~
最后:klogd的小技巧
klogd(内核日志守护进程)是调试的“隐形助手”,注意两点:
1.用1.3-pl3以上版本的sysklogd包,支持地址自动解析;
2.它会通过两种方式解析地址:
◦静态解析:用System.map文件(内核符号表);
◦动态解析:自动获取加载模块的符号表(支持动态调试模块bug);
1.模块加载/卸载后,可重启klogd刷新符号表(具体看klogd手册)。
总结
内核bug调试看似复杂,但只要跟着“识别日志→获取日志→定位代码→报告/修复”的流程走,再借助gdb、get_maintainer.pl等工具,就能从“无从下手”变成“有条理排查”。
这份指南的所有方法都来自内核官方文档,权威且实用——下次遇到内核bug时,不妨按这个流程试试,说不定你就是解决问题的关键人物~
如果有内核调试的经验,欢迎在评论区分享你的小技巧~
- 随机文章
- 热门文章
- 热评文章
- 傅盛:我和李志飞一致认为,发展AI要“产模一体化”
- 深度解析:美测2024新品PRO-B,如何高效赋能美业门店营销运营
- 热潮涌动的人工智能距离科技“奇点”还有多远
- 美高梅集团总裁:积极参与文旅高质量发展,持续加码中国市场
- 乖宝宠物营养研究院弗列加特(上海)研发中心盛大揭幕
- 我国实现碳-14生产全面国产化 秦山核电新成果打破国外垄断
- 受下游铁水产量回升带动 双焦氛围改善
- 白银高位回落后仍面临危险,或进一步跌至26美元
- 商务部:有关“产能过剩”的炒作毫无道理,中方坚决反对
- 中国首颗超500比特超导量子计算芯片正式发布
- 停播32天后疯狂小杨哥回归直播间:引超3000万人围观,销售额最高或达1亿元
- 中央气象台:我国近海海域将有5~7级风
- 未婚未育的90后开始抢着当月嫂,能少走20年弯路吗?
- 1“赛事+”提升城市“流量” 陕西商洛拓经济发展新“赛道”
- 2“五一”临近 持基过节的投资者要注意这几点
- 3华发股份:成功入选“人民优选”品牌 五一黄金周热销30亿
- 4钟鼓楼老街区的古都新事
- 5非常危险!女子摔成粉碎性骨折!又是因为洞洞鞋,夏天多人中招……
- 6金税四期试点上线,财税体制改革拉开帷幕!或有资金借道信创ETF基金(562030)逢跌进场布局
- 7到2027年产业规模达到2000亿元 浙江发布历史经典产业高质量发展计划
- 8初步数据:我国一季度经常账户顺差392亿美元
- 9IDC:24Q1全球PC出货量恢复增长 达到疫情前水平
- 10“发现山西之美”TDC旅游发现者大会举办:共话文旅新生态 邀客体验新玩法
- 11(中国新貌)“国宝”大熊猫:栖居更美境 云游更广天
- 12培养工程领域专业人才 非洲首所交通大学在尼日利亚投入使用
- 13瑞众保险副总裁俞德本出任公司临时负责人
- 1大裁员下,特斯拉两名顶级高管离职
- 2奇瑞将与欧洲高端品牌签署技术平台授权协议
- 32024中国长三角青年企业家交流大会在杭州举办
- 4雷克萨斯GX中东版 全部在售 2023款 2022款 2020款 2019款 2018款成都远卓名车雷克萨斯GX中东版团购钜惠20万 欢迎上门试驾
- 5零跑C16将搭载中创新航磷酸铁锂电池
- 6Q1净利微增7%,宁德时代股东总数较2023年年末减少10728户
- 7哪吒,需要背水一战
- 8“新”中有“机”!创新服务承接新流量 撬动消费升级
- 9非创始版SU7何时交付 小米:工厂生产爬坡 全力提高产能
- 10央媒评卧铺挂帘:谁买的票谁做主
- 11江西南昌首部“多规合一”国土空间总体规划获批
- 12方程豹旗舰硬派越野!豹8正式亮相:仰望U8“青春版”登场
- 13583家族/造型霸气 方程豹豹8量产版发布



