我们的系统是基于 PowerPC 的运行 Linux 的嵌入式系统。我们遇到了随机的 SIGILL 崩溃,这种情况在各种应用程序中都会出现。崩溃的根本原因是将要执行的指令归零。这表明内存中的文本段已损坏。由于文本段是以只读方式加载的,因此应用程序无法损坏它。所以我怀疑某些常见的子系统(DMA?)导致了这种损坏。由于问题需要几天的时间才能重现(由于 SIGILL 导致崩溃),因此调查变得越来越困难。因此,首先我希望能够知道任何应用程序的文本段是否以及何时已损坏。
我查看了堆栈跟踪,所有指针、寄存器都是正确的。
你们有什么建议我该怎么做吗?
一些信息:
Linux 3.12.19-rt30 #1 SMP 3 月 11 日星期五 01:31:24 IST 2016 ppc64 GNU/Linux
(gdb) BT
xxx 中的 0 0x10457dc0
反汇编输出:
=> 0x10457dc0 : 先生 r1,r11
0x10457dc4 :blr
地址 0x10457dc0 处预期指令:0x7d615b78
捕获 SIGILL 0x10457dc0 后发现指令:0x00000000
(gdb) 维护信息部分
0x10006c60->0x106cecac位于0x00006c60:.text ALLOC LOADREADONLY代码有_内容
预期(来自应用程序二进制文件):
(gdb) x /32 0x10457da0
0x10457da0:0x913e0000 0x4bff4f5d 0x397f0020 0x800b0004
0x10457db0:0x83abfff4 0x83cbfff8 0x7c0803a6 0x83ebfffc
0x10457dc0:0x7d615b780x4e800020 0x7c7d1b78 0x7fc3f378
0x10457dd0:0x4bcd8be5 0x7fa3eb78 0x4857e109 0x9421fff0
实际(处理 SIGILL 并转储附近的内存位置后):
错误指令地址:0x10457dc0
0x10457da0:0x913E0000
0x10457db0:0x83ABFFF4
=> 0x10457dc0:0x00000000
0x10457dd0:0x4BCD8BE5
0x10457de0:0x93E1000C
Edit:
我们得到的一条线索是,损坏总是发生在以 0xdc0 结尾的偏移处。
例如
错误指令地址:0x10653dc0错误指令地址:0x1000ddc0flash_erase[8557]:未处理的信号 40fed6dc0咬合 0fed6dc0 lr 0fed6dac 代码 30001
nandwrite[8561]:未处理的信号 40fed6dc0咬合 0fed6dc0 lr 0fed6dac 代码 30001
awk[4448]: 未处理的信号 40fe09dc0咬合 0fe09dc0 lr 0fe09dbc 代码 30001
awk[16002]:未处理的信号 40fe09dc0咬合 0fe09dc0 lr 0fe09dbc 代码 30001
getStats[20670]:未处理的信号 40fecfdc0nip 0fecfdc0 lr 0fecfdbc 代码 30001
expr[27923]:未处理的信号 40fe74dc0咬合 0fe74dc0 lr 0fe74dc0 代码 30001
编辑 2:另一个线索是损坏总是发生在物理帧编号 0x00a4d 处。我想当 PAGE_SIZE 为 4096 时,这会转换为物理地址 0x00A4DDC0。我们怀疑我们的几个内核驱动程序并进一步调查。有没有更好的想法(比如放置硬件观察点)可以更有效?下面建议的 KASAN 怎么样?
任何帮助表示赞赏。谢谢。