我有一些处理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中。
答案 0 :(得分:0)
在Linux上,您可以使用_syscall。 另一种方法是将errno保存在信号处理程序的开头,并在返回之前还原。 如果您确定函数在这方面是安全的,则还可以使用某些属性(在GCC和CLANG中)来禁用对函数的检测。