ThreadSanitizer:信号处理程序破坏了errno-如何避免设置errno

时间:2018-12-06 15:13:07

标签: multithreading thread-safety posix

我有一些处理POSIX信号的代码,并且作为一部分(为了信号安全)-进行sem_post()系统调用(根据http://man7.org/linux/man-pages/man3/sem_post.3.html“异步信号安全”)。

但是,当我运行此代码时-偶尔,我会收到线程消毒剂投诉:

摘要:ThreadSanitizer:信号处理程序破坏了errno /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/SignalHandlers.cpp:497在Stroika :: Foundation :: Execution: :SignalHandlerRegistry :: FirstPassSignalHandler_(int)

我相信这是由于对sem_post的调用所致,它实际上可能会覆盖errno。

是的-如果恰好在(错误​​的)时间发生,这确实可能使另一个线程混乱。

我一直都发现“线程本地” errno机制是处理错误的便捷方法,但我现在才意识到信号处理代码的危险性。

是否有某种方法可以在不覆盖errno的情况下调用系统调用?至少有些隐约可移植?

甚至http://man7.org/linux/man-pages/man2/syscall.2.html-表示将结果存储在errno中。

1 个答案:

答案 0 :(得分:0)

在Linux上,您可以使用_syscall。 另一种方法是将errno保存在信号处理程序的开头,并在返回之前还原。 如果您确定函数在这方面是安全的,则还可以使用某些属性(在GCC和CLANG中)来禁用对函数的检测。