7.1 两起排错实录:probe 失败与中断失踪


7.1 两起排错实录:probe 失败与中断失踪

本节摘要:两起真实故障的完整破案过程。案例一:模块加载成功但 probe 静默失败,层层排查设备模型与匹配链路;案例二:系统唤醒后按键全部失灵,电源域与中断状态的叠加分析。每个结论都有证据,每个误判都有解释。

排错实录的价值不在答案,在路径。以下两案都按"现象、排查、误判、根因、修复、沉淀"六段展开——请注意排查者在哪里走弯路,以及是什么证据把方向纠正回来。

案例一:加载成功的驱动,没被调用

现象:新板子点亮,LED 驱动模块装入顺利,系统日志无任何报错,但设备文件不出现、灯不亮。开发板上个月在旧板子验证过一切正常。

第一步:确认装入状态

$ lsmod | grep board-led board_led 12288 0 $ dmesg | grep -i led (空——模块装入后连一条日志都没有)

模块在内核里,但初始化路径一条日志都没打——init 日志都没有,说明问题比"probe 不来"更靠前。这里开发者的第一反应是"模块坏了",重编重装三次,无效。这是典型的无证据试错:三次重装没有产生任何新信息。

第二步:检查模块初始化日志为何缺失。细看代码:模块用了 module_platform_driver 宏,注册平台驱动是 init 里唯一的动作,宏本身不打日志——"无日志"其实是正常现象,不是故障线索。这个误判的教训:先确认"预期行为是什么",再判断"异常"。

第三步:检查驱动与设备的注册状态。系统目录下能看到两边的清单:

$ ls /sys/bus/platform/devices/ | grep led (空——设备侧根本没有 LED 设备!) $ ls /sys/bus/platform/drivers/board-led/ bind uevent unbind # 驱动在册,但没有绑定任何设备

责任段锁定:不是驱动不匹配,是设备压根不存在。设备从哪来?第 4.2 节的链路——设备树节点展开成平台设备。查树的运行时视图:

$ ls /proc/device-tree/ | grep -i led led(节点在) $ ls /proc/device-tree/led/ compatible name led-gpio reg $ cat /proc/device-tree/led/compatible vendor,board-led2 ← 大小写与拼写和旧板不同!

根因落定:新板子的设备树由硬件团队重新提供,compatible 写成了"vendor,board-led2",而驱动匹配表里登记的是"vendor,board-led"——一字之差,匹配必败,且失败完全静默(匹配不上不算错误,双方只是各自等待)。

修复与沉淀:匹配表补上第二个兼容串(保留旧的以兼容旧板)。沉淀两条:其一,匹配表写成多条目是惯例,硬件改版不换驱动;其二,排查"probe 不来"的标准顺序是先查设备在不在,再查匹配对不对——设备侧空了,匹配表怎么改都没用。

案例二:唤醒之后,按键集体失灵

现象:物联网网关首批样机老化测试中,约每二十次休眠唤醒出现一次"所有按键无响应",LED 照常工作。故障复现概率低,且一旦出现必须重启才能恢复。

第一步:定位责任段。按 1.1 节的责任表拆解:按键无响应、LED 正常——两者共用同一颗主控,驱动各自独立。按键链路是"引脚中断、中断处理、等待队列、用户态轮询"四段。逐段探测:用户态轮询正常打开设备(设备文件在、打开成功);等待队列无人唤醒——中断没来

第二步:中断为什么不来

$ cat /proc/interrupts | grep key 43: 128054 ... GICv3 43 Level keys (唤醒后立刻查看) 43: 128054 ... GICv3 43 Level keys ← 计数纹丝不动:按键按下时中断根本没有抵达内核

中断计数不动,嫌疑两选一:中断控制器没放行,或设备侧没发出。用示波器看引脚:按键按下电平正常翻转——设备侧在发。再看控制器侧的中断使能状态:休眠挂起路径里,平台代码会临时屏蔽中断,恢复路径应重新开启;出故障的机器上该中断的使能位仍是屏蔽态

第三步:为什么恢复路径没开中断。中断的屏蔽与恢复是电源管理框架按设备驱动回调编排的。查按键驱动,它把挂起与恢复回调挂在了引脚控制设备而非自己头上——这套"借用"在旧内核上恰好能跑,新内核的恢复顺序调整后,按键驱动的恢复回调不再被调用。更深层的问题浮出:按键所在的电源域在休眠中真的断过电,而驱动从未声明这一点,寄存器状态恢复全靠运气。

根因落定:两层叠加——中断使能恢复路径依赖了未声明的顺序(软件层),电源域断电后寄存器丢失未重配(硬件层)。单独哪一层都未必立刻出事,叠加后以低概率出现"中断屏蔽+状态丢失"的组合。

修复与沉淀:驱动声明自己的电源回调,恢复里重配引脚与中断;匹配表与电源域声明对齐硬件手册。沉淀:低概率故障优先怀疑"状态未恢复"类根因——竞态、泄流这类"活性"故障通常每次表现随机,而"偶发的固定失效"多半是状态残留;概率低只是因为触发条件(特定休眠时序)本身罕见。

两案排错路径对照

两案排错路径对照

排错方法论的收敛

两案合看,可提炼出一张通用流程:现象登记(什么坏了、多稳定、什么条件下出现)→ 责任段定位(用 1.1 节那张表把链路切段,逐段探活)→ 假设枚举(每段列出可能原因,按检查成本排序)→ 证据采集(一条实验或一份系统状态,只回答一个问题)→ 根因收敛(能解释全部现象的原因才算根因,只解释一半的是下一个假设)。

最后的"解释全部现象"是最容易被忽略的验收标准:案例二里"中断控制器屏蔽"能解释按键失灵,却解释不了"为何重启才能恢复"——直到电源域一层补上,全部现象才闭环。

常见追问

追问一:两起案例排查时走的是最短路径吗?中间的误判浪费了吗? 不是最短路径,误判也没浪费。案例一在"设备没注册"上停留过——先入为主地相信设备树节点没问题,直到把匹配字符串逐字比对才翻案;案例二先怀疑过按键驱动本身,空跑了一轮压测。这些弯路的共同点是用假设代替了证据,而每次翻案的瞬间恰恰是机制理解加深最快的时刻。实录保留弯路,就是要让你体会"证据先于直觉"不是一句口号,而是每次省下半小时的具体动作。

追问二:现场没有第二个好板子做对照,怎么继续排查? 对照不是必需品,记录才是。两案的关键证据全部来自单板自身:设备清单、中断计数、电源域状态,都是"与自己预期"的对照。好板子的价值在于快速二分"硬件坏还是软件错",没有它就把这一步拆成仪器测量与寄存器回读——万用表量供电、回读关键寄存器与手册对值。排错的底气来自可观测性,而可观测性一半是设备给的,一半是你写驱动时留的探针给的——第 8 章讲发布维护时,会把这些探针列为出厂交付物的一部分。

本节要点回顾

  • 先查设备在不在,再查匹配对不对:匹配失败是静默的,双方各自等待不报错。
  • 无日志未必是故障:先明确预期行为,再判断异常。
  • 中断计数是活体探针:计数走动说明信号链通,纹丝不动往上游查。
  • 低概率固定失效先查状态残留:偶发不等于竞态,触发条件罕见的状态 bug 同样偶发。
  • 根因必须解释全部现象:只解释一半的,只是下一个假设。

两起实录靠机制理解破案,但很多问题根本不该活到调试阶段——下一节看静态分析如何在代码写完的瞬间就把它们揪出来。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U