nanosleep()系统调用唤醒总线错误?

时间:2011-09-26 14:20:09

标签: linux handler sleep signals sigbus

我正在从嵌入式MIPS Linux应用程序中查看核心转储。 GDB正在报告SIGBUS,并且处理信号的线程似乎位于系统调用中以进行nanosleep - 更高级别的代码基本上称为睡眠(非常长时间); 假设另一个进程没有将该信号发送给应用程序,会导致此线程被唤醒的原因是什么?内核中有什么东西产生了总线错误吗?它可能是由另一个阻止此类信号的线程引起的吗? (请原谅任何天真,我不太了解信号)。感谢。

1 个答案:

答案 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错误。