sem_post() called from inside signal handler, and can spoil errno

Description

This occurs VERY RARELY:
==================
WARNING: ThreadSanitizer: signal handler spoils errno (pid=1101)
#0 Stroika::Foundation::Execution::SignalHandlerRegistry::FirstPassSignalHandler_(int) /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/SignalHandlers.cpp:497 (Test38+0x000000b55bc4)
#1 _gnu_debug::_Safe_sequence_base::_M_detach(_gnu_debug::_Safe_iterator_base*) <null> (Test38+0x000000efcab3)
#2 _gnu_debug::_Safe_iterator<std::_Rb_tree_const_iterator<std::thread::id>, std::_debug::multiset<std::thread::id, std::less<std::thread::id>, std::allocator<std::thread::id> > >::~_Safe_iterator() /usr/include/c++/7/debug/safe_iterator.h:86 (Test38+0x000000b39cc9)
#3 Stroika::Foundation:ebug::AssertExternallySynchronizedLock::unlock_shared_() const /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Debug/AssertExternallySynchronizedLock.cpp:82 (Test38+0x000000b38d43)
#4 Stroika::Foundation:ebug::AssertExternallySynchronizedLock::unlock_shared() const ../Characters/../Containers/../Traversal/../Debug/AssertExternallySynchronizedLock.inl:88 (Test38+0x00000098e555)
#5 std::shared_lock<Stroika::Foundation:ebug::AssertExternallySynchronizedLock const>::~shared_lock() /usr/include/c++/7/shared_mutex:579 (Test38+0x000000995931)
#6 Stroika::Foundation::Traversal::Iterable<Stroika::Foundation::Characters::Character>::_SafeReadRepAccessor<Stroika::Foundation::Characters::String::_IRep>::~_SafeReadRepAccessor() ../Containers/../Traversal/Iterable.h:1122 (Test38+0x00000098fbdb)
#7 Stroika::Foundation::Characters::String::_AssertRepValidType() const ../Characters/String.inl:203 (Test38+0x00000098fcce)
#8 Stroika::Foundation::Characters::String::String(wchar_t const*, wchar_t const*) ../Characters/String.inl:127 (Test38+0x000000a75fa1)
#9 Stroika::Foundation::Characters::StringBuilder::str() const ../Characters/StringBuilder.inl:242 (Test38+0x000000a7a84e)
#10 Stroika::Foundation::Execution::Thread::Rep_::ToString() const /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/Thread.cpp:363 (Test38+0x000000c5d93c)
#11 Stroika::Foundation::Execution::Thread:tr::ToString() const /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/Thread.cpp:836 (Test38+0x000000c605c3)
#12 Stroika::Foundation::Execution::Thread:tr::Start() const /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/Thread.cpp:843 (Test38+0x000000c606a0)
#13 operator() /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Tests/38/Test.cpp:628 (Test38+0x000000963267)
#14 _M_invoke /usr/include/c++/7/bits/std_function.h:316 (Test38+0x000000973e85)
#15 std::function<void ()>::operator()() const /usr/include/c++/7/bits/std_function.h:706 (Test38+0x00000099c38c)
#16 Stroika::Foundation::Execution::Thread::Rep_::Run_() /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/Thread.cpp:340 (Test38+0x000000c5d3d1)
#17 Stroika::Foundation::Execution::Thread::Rep_::ThreadMain_(std::shared_ptr<Stroika::Foundation::Execution::Thread::Rep_> const*) /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/Thread.cpp:615 (Test38+0x000000c5e995)
#18 operator() /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/Thread.cpp:302 (Test38+0x000000c5cd52)
#19 _invoke_impl<void, Stroika::Foundation::Execution::Thread::Rep:oCreate(const std::shared_ptr<Stroika::Foundation::Execution::Thread::Rep_>*)::<lambda()> > /usr/include/c++/7/bits/invoke.h:60 (Test38+0x000000c64cbb)
#20 _invoke<Stroika::Foundation::Execution::Thread::Rep:oCreate(const std::shared_ptr<Stroika::Foundation::Execution::Thread::Rep_>*)::<lambda()> > /usr/include/c++/7/bits/invoke.h:95 (Test38+0x000000c6387c)
#21 _M_invoke<0> /usr/include/c++/7/thread:234 (Test38+0x000000c684a0)
#22 operator() /usr/include/c++/7/thread:243 (Test38+0x000000c683af)
#23 _M_run /usr/include/c++/7/thread:186 (Test38+0x000000c6831b)
#24 execute_native_thread_routine <null> (Test38+0x000000f0356e)

SUMMARY: ThreadSanitizer: signal handler spoils errno /home/lewis/Sandbox/Stroika-Build-Dir-Ubuntu1804_x86_64/Library/Sources/Stroika/Foundation/Execution/SignalHandlers.cpp:497 in Stroika::Foundation::Execution::SignalHandlerRegistry::FirstPassSignalHandler_(int)
==================

And quite clear what this report is referring to. But note:
SignalHandlerRegistry::FirstPassSignalHandler_ () CALLS
tmp->NotifyOfArrivalOfPossiblySafeSignal () calls
tell2WakeAfterDataUpdate_ () whcih calls
fRecievedSig_.Set (); - aka SemWaitableEvent::Set ()
which calls sem_post ()

Posted question to
https://stackoverflow.com/questions/53654385/threadsanitizer-signal-handler-spoils-errno-how-to-avoid-set-of-errno

created tsan suppression for now.

Environment

None

Status

Assignee

Lewis Pringle

Reporter

Lewis Pringle

Labels

None

Components

Priority

Medium
Configure