我正在从嵌入式MIPS Linux应用程序中查看核心转储。 GDB正在报告SIGBUS,并且处理信号的线程似乎位于系统调用中以进行nanosleep - 更高级别的代码基本上称为睡眠(非常长时间); 假设另一个进程没有将该信号发送给应用程序,会导致此线程被唤醒的原因是什么?内核中有什么东西产生了总线错误吗?它可能是由另一个阻止此类信号的线程引起的吗? (请原谅任何天真,我不太了解信号)。感谢。
答案 0 :(得分:3)
如果将si_pid
设置为地址,则表示您的SIGBUS是由程序中的错误引发的。通常,当内核尝试在某些程序文本中进行分页但遇到IO错误时会发生这种情况。堆栈溢出也可以触发它。
您看到si_pid
设置为地址,因为si_pid
是联盟的一部分,并且si_address
有别名。特别是,si_pid
仅在si_code == SI_USER
时有效。您可以从si_code
成员获取更多信息:
The following values can be placed in si_code for a SIGBUS signal:
BUS_ADRALN invalid address alignment
BUS_ADRERR nonexistent physical address
BUS_OBJERR object-specific hardware error
BUS_MCEERR_AR (since Linux 2.6.32)
Hardware memory error consumed on a machine check; action required.
BUS_MCEERR_AO (since Linux 2.6.32)
Hardware memory error detected in process but not consumed; action optional.
请注意,无法阻止内核发起的SIGBUS信号 - 如果您尝试这样做,您的程序将会终止。
我怀疑你的调试器在这里可能会对SIGBUS信号的来源感到困惑;它可能归因于错误的线程。您可能想要检查进程的其他线程,看看它们是否做了奇怪的事情。或者,从nanosleep
返回并在返回地址的代码页中进行分页时,可能会遇到IO错误。