You can use GetConsoleMode in a way similar to isatty to determine if stdin is a terminal.  If it is a terminal, you can use  PeekConsoleInput or GetNumberOfConsoleInputEvents to determine if there's data waiting without blocking.  The two of these combined should allow you to implement a select-like loop, but this loop will structurally be very different from what the non windows side will look like.  <br><br>As far as I know there is no better way to achieve this.<br><div class="gmail_quote">On Fri, May 15, 2015 at 3:57 AM Pavel Labath <<a href="mailto:labath@google.com">labath@google.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all,<br>
<br>
I have identified a lot of IOHandler races by manual code inspection.<br>
I have a mostly-working fix for this, but I am still polishing it, and<br>
will send it for review shortly.<br>
<br>
The reason I say only "mostly" working is that I am not sure how to<br>
handle IOHandlerEditline::Cancel on windows. Specifically, the<br>
behavior of the handler when libedit is disabled. Currently Cancel()<br>
and Interrupt() correctly interrupt the handler, but only when libedit<br>
is in use. When libedit is off the IOHandler does a simple blocking<br>
fgets to read the command. This is a problem since we cannot interrupt<br>
the handler when we push another handler on top of the IO stack. Now,<br>
I could implement this to use select(), but this will not work work on<br>
windows.<br>
<br>
Zachary, do you have any idea how could the Cancel() functionality be<br>
implemented on windows? For now, I think I implement things in a way<br>
that the missing cancelation problem will not be extremely annoying,<br>
but in general, we should find a way to deal with this in the future.<br>
I think I remember seeing also other places that needed a select<br>
replacement on windows.<br>
<br>
cheers,<br>
pl<br>
<br>
<br>
<br>
On 15 May 2015 at 01:38, Zachary Turner <<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>> wrote:<br>
> Great results! I'm especially interested in these IOHandler issues, since we<br>
> know for sure there are problems here.<br>
><br>
> When you say Python can't find tsan, can you elaborate? I'm not sure how<br>
> tsan works or the process used to run lldb under tsan, but i bet it's<br>
> something we can figure out with more information.<br>
><br>
> Also, what os is this on?<br>
><br>
> On Thu, May 14, 2015 at 5:01 PM Ryan Brown <<a href="mailto:ribrdb@google.com" target="_blank">ribrdb@google.com</a>> wrote:<br>
>><br>
>> I just built lldb with tsan. The tests don't seem to work because python<br>
>> can't find tsan, but a quick debugging session found a few issues:<br>
>><br>
>> WARNING: ThreadSanitizer: data race (pid=64299)<br>
>>   Write of size 1 at 0x7d4400004bb0 by thread T6:<br>
>>     #0 lldb_private::IOHandler::SetIsDone(bool)<br>
>> tools/lldb/include/lldb/Core/IOHandler.h:107<br>
>>     #1 lldb_private::Process::PushProcessIOHandler()<br>
>> tools/lldb/source/Target/Process.cpp:5279<br>
>>     #2<br>
>> lldb_private::Process::HandlePrivateEvent(std::shared_ptr<lldb_private::Event>&)<br>
>> tools/lldb/source/Target/Process.cpp:4443<br>
>>     #3 lldb_private::Process::RunPrivateStateThread()<br>
>> tools/lldb/source/Target/Process.cpp:4581<br>
>>     #4 lldb_private::Process::PrivateStateThread(void*)<br>
>> tools/lldb/source/Target/Process.cpp:4505<br>
>>     #5 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:81<br>
>><br>
>>   Previous write of size 1 at 0x7d4400004bb0 by main thread:<br>
>>     #0 lldb_private::IOHandler::SetIsDone(bool)<br>
>> tools/lldb/include/lldb/Core/IOHandler.h:107<br>
>>     #1 IOHandlerProcessSTDIO::Run()<br>
>> tools/lldb/source/Target/Process.cpp:5096<br>
>>     #2 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:907<br>
>>     #3 lldb_private::CommandInterpreter::RunCommandInterpreter(bool, bool,<br>
>> lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #4 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #5 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #6 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>> ==================<br>
>> WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)<br>
>> (pid=64299)<br>
>>   Cycle in lock order graph: M31728 (0x7d1000019e58) => M564<br>
>> (0x7d680001d0f8) => M31728<br>
>><br>
>>   Mutex M564 acquired here while holding mutex M31728 in main thread:<br>
>>     #3 Locker tools/lldb/source/Host/common/Mutex.cpp:114<br>
>>     #4<br>
>> lldb_private::ModuleList::FindSymbolsWithNameAndType(lldb_private::ConstString<br>
>> const&, lldb::SymbolType, lldb_private::SymbolContextList&, bool) const<br>
>> tools/lldb/source/Core/ModuleList.cpp:565<br>
>>     #5 JITLoaderGDB::GetSymbolAddress(lldb_private::ModuleList&,<br>
>> lldb_private::ConstString const&, lldb::SymbolType) const<br>
>> tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp:432<br>
>>     #6 JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList&)<br>
>> tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp:109<br>
>>     #7 JITLoaderGDB::DidLaunch()<br>
>> tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp:84<br>
>>     #8 lldb_private::JITLoaderList::DidLaunch()<br>
>> tools/lldb/source/Target/JITLoaderList.cpp:60<br>
>>     #9 lldb_private::Process::Launch(lldb_private::ProcessLaunchInfo&)<br>
>> tools/lldb/source/Target/Process.cpp:3177<br>
>>     #10<br>
>> lldb_private::platform_linux::PlatformLinux::DebugProcess(lldb_private::ProcessLaunchInfo&,<br>
>> lldb_private::Debugger&, lldb_private::Target*, lldb_private::Error&)<br>
>> tools/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp:805<br>
>>     #11 lldb_private::Target::Launch(lldb_private::ProcessLaunchInfo&,<br>
>> lldb_private::Stream*) tools/lldb/source/Target/Target.cpp:2602<br>
>>     #12 CommandObjectProcessLaunch::DoExecute(lldb_private::Args&,<br>
>> lldb_private::CommandReturnObject&)<br>
>> tools/lldb/source/Commands/CommandObjectProcess.cpp:263<br>
>>     #13 lldb_private::CommandObjectParsed::Execute(char const*,<br>
>> lldb_private::CommandReturnObject&)<br>
>> tools/lldb/source/Interpreter/CommandObject.cpp:1075<br>
>>     #14 lldb_private::CommandInterpreter::HandleCommand(char const*,<br>
>> lldb_private::LazyBool, lldb_private::CommandReturnObject&,<br>
>> lldb_private::ExecutionContext*, bool, bool)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:1812<br>
>>     #15<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:2997<br>
>>     #16 non-virtual thunk to<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:3076<br>
>>     #17 lldb_private::IOHandlerEditline::Run()<br>
>> tools/lldb/source/Core/IOHandler.cpp:729<br>
>>     #18 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:907<br>
>>     #19 lldb_private::CommandInterpreter::RunCommandInterpreter(bool,<br>
>> bool, lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #20 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #21 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #22 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>>   Mutex M31728 previously acquired by the same thread here:<br>
>>     #3 Locker tools/lldb/source/Host/common/Mutex.cpp:114<br>
>>     #4 lldb_private::JITLoaderList::DidLaunch()<br>
>> tools/lldb/source/Target/JITLoaderList.cpp:58<br>
>>     #5 lldb_private::Process::Launch(lldb_private::ProcessLaunchInfo&)<br>
>> tools/lldb/source/Target/Process.cpp:3177<br>
>>     #6<br>
>> lldb_private::platform_linux::PlatformLinux::DebugProcess(lldb_private::ProcessLaunchInfo&,<br>
>> lldb_private::Debugger&, lldb_private::Target*, lldb_private::Error&)<br>
>> tools/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp:805<br>
>>     #7 lldb_private::Target::Launch(lldb_private::ProcessLaunchInfo&,<br>
>> lldb_private::Stream*) tools/lldb/source/Target/Target.cpp:2602<br>
>>     #8 CommandObjectProcessLaunch::DoExecute(lldb_private::Args&,<br>
>> lldb_private::CommandReturnObject&)<br>
>> tools/lldb/source/Commands/CommandObjectProcess.cpp:263<br>
>>     #9 lldb_private::CommandObjectParsed::Execute(char const*,<br>
>> lldb_private::CommandReturnObject&)<br>
>> tools/lldb/source/Interpreter/CommandObject.cpp:1075<br>
>>     #10 lldb_private::CommandInterpreter::HandleCommand(char const*,<br>
>> lldb_private::LazyBool, lldb_private::CommandReturnObject&,<br>
>> lldb_private::ExecutionContext*, bool, bool)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:1812<br>
>>     #11<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:2997<br>
>>     #12 non-virtual thunk to<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:3076<br>
>>     #13 lldb_private::IOHandlerEditline::Run()<br>
>> tools/lldb/source/Core/IOHandler.cpp:729<br>
>>     #14 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:907<br>
>>     #15 lldb_private::CommandInterpreter::RunCommandInterpreter(bool,<br>
>> bool, lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #16 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #17 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #18 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>>   Mutex M31728 acquired here while holding mutex M564 in thread T6:<br>
>>     #3 Locker tools/lldb/source/Host/common/Mutex.cpp:114<br>
>>     #4<br>
>> lldb_private::JITLoaderList::ModulesDidLoad(lldb_private::ModuleList&)<br>
>> tools/lldb/source/Target/JITLoaderList.cpp:74<br>
>>     #5 lldb_private::Process::ModulesDidLoad(lldb_private::ModuleList&)<br>
>> tools/lldb/source/Target/Process.cpp:6466<br>
>>     #6 lldb_private::Target::ModulesDidLoad(lldb_private::ModuleList&)<br>
>> tools/lldb/source/Target/Target.cpp:1286<br>
>>     #7 lldb_private::Target::ModuleAdded(lldb_private::ModuleList const&,<br>
>> std::shared_ptr<lldb_private::Module> const&)<br>
>> tools/lldb/source/Target/Target.cpp:1254<br>
>>     #8 non-virtual thunk to<br>
>> lldb_private::Target::ModuleAdded(lldb_private::ModuleList const&,<br>
>> std::shared_ptr<lldb_private::Module> const&)<br>
>> tools/lldb/source/Target/Target.cpp:1256<br>
>>     #9<br>
>> lldb_private::ModuleList::AppendImpl(std::shared_ptr<lldb_private::Module><br>
>> const&, bool) tools/lldb/source/Core/ModuleList.cpp:111<br>
>>     #10<br>
>> lldb_private::ModuleList::Append(std::shared_ptr<lldb_private::Module><br>
>> const&) tools/lldb/source/Core/ModuleList.cpp:118<br>
>>     #11 lldb_private::Target::GetSharedModule(lldb_private::ModuleSpec<br>
>> const&, lldb_private::Error*) tools/lldb/source/Target/Target.cpp:1810<br>
>>     #12<br>
>> lldb_private::DynamicLoader::LoadModuleAtAddress(lldb_private::FileSpec<br>
>> const&, unsigned long, unsigned long)<br>
>> tools/lldb/source/Core/DynamicLoader.cpp:185<br>
>>     #13 DynamicLoaderPOSIXDYLD::LoadAllCurrentModules()<br>
>> tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp:530<br>
>>     #14 DynamicLoaderPOSIXDYLD::EntryBreakpointHit(void*,<br>
>> lldb_private::StoppointCallbackContext*, unsigned long, unsigned long)<br>
>> tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp:343<br>
>>     #15<br>
>> lldb_private::BreakpointOptions::InvokeCallback(lldb_private::StoppointCallbackContext*,<br>
>> unsigned long, unsigned long)<br>
>> tools/lldb/source/Breakpoint/BreakpointOptions.cpp:147<br>
>>     #16<br>
>> lldb_private::Breakpoint::InvokeCallback(lldb_private::StoppointCallbackContext*,<br>
>> int) tools/lldb/source/Breakpoint/Breakpoint.cpp:345<br>
>>     #17<br>
>> lldb_private::BreakpointLocation::InvokeCallback(lldb_private::StoppointCallbackContext*)<br>
>> tools/lldb/source/Breakpoint/BreakpointLocation.cpp:222<br>
>>     #18<br>
>> lldb_private::BreakpointLocation::ShouldStop(lldb_private::StoppointCallbackContext*)<br>
>> tools/lldb/source/Breakpoint/BreakpointLocation.cpp:465<br>
>>     #19<br>
>> lldb_private::BreakpointLocationCollection::ShouldStop(lldb_private::StoppointCallbackContext*)<br>
>> tools/lldb/source/Breakpoint/BreakpointLocationCollection.cpp:144<br>
>>     #20<br>
>> lldb_private::BreakpointSite::ShouldStop(lldb_private::StoppointCallbackContext*)<br>
>> tools/lldb/source/Breakpoint/BreakpointSite.cpp:69<br>
>>     #21<br>
>> lldb_private::StopInfoBreakpoint::ShouldStopSynchronous(lldb_private::Event*)<br>
>> tools/lldb/source/Target/StopInfo.cpp:200<br>
>>     #22 lldb_private::Thread::ShouldStop(lldb_private::Event*)<br>
>> tools/lldb/source/Target/Thread.cpp:845<br>
>>     #23 lldb_private::ThreadList::ShouldStop(lldb_private::Event*)<br>
>> tools/lldb/source/Target/ThreadList.cpp:318<br>
>>     #24 lldb_private::Process::ShouldBroadcastEvent(lldb_private::Event*)<br>
>> tools/lldb/source/Target/Process.cpp:4181<br>
>>     #25<br>
>> lldb_private::Process::HandlePrivateEvent(std::shared_ptr<lldb_private::Event>&)<br>
>> tools/lldb/source/Target/Process.cpp:4422<br>
>>     #26 lldb_private::Process::RunPrivateStateThread()<br>
>> tools/lldb/source/Target/Process.cpp:4581<br>
>>     #27 lldb_private::Process::PrivateStateThread(void*)<br>
>> tools/lldb/source/Target/Process.cpp:4505<br>
>>     #28 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:81<br>
>><br>
>>   Mutex M564 previously acquired by the same thread here:<br>
>>     #3 Locker tools/lldb/source/Host/common/Mutex.cpp:114<br>
>>     #4<br>
>> lldb_private::ModuleList::AppendImpl(std::shared_ptr<lldb_private::Module><br>
>> const&, bool) tools/lldb/source/Core/ModuleList.cpp:108<br>
>>     #5<br>
>> lldb_private::ModuleList::Append(std::shared_ptr<lldb_private::Module><br>
>> const&) tools/lldb/source/Core/ModuleList.cpp:118<br>
>>     #6 lldb_private::Target::GetSharedModule(lldb_private::ModuleSpec<br>
>> const&, lldb_private::Error*) tools/lldb/source/Target/Target.cpp:1810<br>
>>     #7<br>
>> lldb_private::DynamicLoader::LoadModuleAtAddress(lldb_private::FileSpec<br>
>> const&, unsigned long, unsigned long)<br>
>> tools/lldb/source/Core/DynamicLoader.cpp:185<br>
>>     #8 DynamicLoaderPOSIXDYLD::LoadAllCurrentModules()<br>
>> tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp:530<br>
>>     #9 DynamicLoaderPOSIXDYLD::EntryBreakpointHit(void*,<br>
>> lldb_private::StoppointCallbackContext*, unsigned long, unsigned long)<br>
>> tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp:343<br>
>>     #10<br>
>> lldb_private::BreakpointOptions::InvokeCallback(lldb_private::StoppointCallbackContext*,<br>
>> unsigned long, unsigned long)<br>
>> tools/lldb/source/Breakpoint/BreakpointOptions.cpp:147<br>
>>     #11<br>
>> lldb_private::Breakpoint::InvokeCallback(lldb_private::StoppointCallbackContext*,<br>
>> int) tools/lldb/source/Breakpoint/Breakpoint.cpp:345<br>
>>     #12<br>
>> lldb_private::BreakpointLocation::InvokeCallback(lldb_private::StoppointCallbackContext*)<br>
>> tools/lldb/source/Breakpoint/BreakpointLocation.cpp:222<br>
>>     #13<br>
>> lldb_private::BreakpointLocation::ShouldStop(lldb_private::StoppointCallbackContext*)<br>
>> tools/lldb/source/Breakpoint/BreakpointLocation.cpp:465<br>
>>     #14<br>
>> lldb_private::BreakpointLocationCollection::ShouldStop(lldb_private::StoppointCallbackContext*)<br>
>> tools/lldb/source/Breakpoint/BreakpointLocationCollection.cpp:144<br>
>>     #15<br>
>> lldb_private::BreakpointSite::ShouldStop(lldb_private::StoppointCallbackContext*)<br>
>> tools/lldb/source/Breakpoint/BreakpointSite.cpp:69<br>
>>     #16<br>
>> lldb_private::StopInfoBreakpoint::ShouldStopSynchronous(lldb_private::Event*)<br>
>> tools/lldb/source/Target/StopInfo.cpp:200<br>
>>     #17 lldb_private::Thread::ShouldStop(lldb_private::Event*)<br>
>> tools/lldb/source/Target/Thread.cpp:845<br>
>>     #18 lldb_private::ThreadList::ShouldStop(lldb_private::Event*)<br>
>> tools/lldb/source/Target/ThreadList.cpp:318<br>
>>     #19 lldb_private::Process::ShouldBroadcastEvent(lldb_private::Event*)<br>
>> tools/lldb/source/Target/Process.cpp:4181<br>
>>     #20<br>
>> lldb_private::Process::HandlePrivateEvent(std::shared_ptr<lldb_private::Event>&)<br>
>> tools/lldb/source/Target/Process.cpp:4422<br>
>>     #21 lldb_private::Process::RunPrivateStateThread()<br>
>> tools/lldb/source/Target/Process.cpp:4581<br>
>>     #22 lldb_private::Process::PrivateStateThread(void*)<br>
>> tools/lldb/source/Target/Process.cpp:4505<br>
>>     #23 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:81<br>
>><br>
>> ==================<br>
>> WARNING: ThreadSanitizer: data race (pid=64299)<br>
>>   Write of size 1 at 0x7d4400004bb1 by thread T2 (mutexes: write M168):<br>
>>     #0 lldb_private::IOHandler::Deactivate()<br>
>> tools/lldb/include/lldb/Core/IOHandler.h:131<br>
>>     #1<br>
>> lldb_private::Debugger::PopIOHandler(std::shared_ptr<lldb_private::IOHandler><br>
>> const&) tools/lldb/source/Core/Debugger.cpp:1064<br>
>>     #2 lldb_private::Process::PopProcessIOHandler()<br>
>> tools/lldb/source/Target/Process.cpp:5291<br>
>>     #3<br>
>> lldb_private::Debugger::HandleProcessEvent(std::shared_ptr<lldb_private::Event><br>
>> const&) tools/lldb/source/Core/Debugger.cpp:1544<br>
>>     #4 lldb_private::Debugger::DefaultEventHandler()<br>
>> tools/lldb/source/Core/Debugger.cpp:1634<br>
>>     #5 lldb_private::Debugger::EventHandlerThread(void*)<br>
>> tools/lldb/source/Core/Debugger.cpp:1696<br>
>>     #6 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:81<br>
>><br>
>>   Previous write of size 1 at 0x7d4400004bb1 by main thread:<br>
>>     #0 lldb_private::IOHandler::Activate()<br>
>> tools/lldb/include/lldb/Core/IOHandler.h:125<br>
>>     #1 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:906<br>
>>     #2 lldb_private::CommandInterpreter::RunCommandInterpreter(bool, bool,<br>
>> lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #3 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #4 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #5 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>> ==================<br>
>> WARNING: ThreadSanitizer: data race (pid=64299)<br>
>>   Read of size 8 at 0x7da0000080c0 by thread T2 (mutexes: write M168):<br>
>>     #0 write <null>:0<br>
>>     #1 operator() tools/lldb/source/Host/posix/PipePosix.cpp:416<br>
>>     #2 std::_Function_handler<lldb_private::Error (bool&),<br>
>> lldb_private::PipePosix::Write(void const*, unsigned long, unsigned<br>
>> long&)::$_1>::_M_invoke(std::_Any_data const&, bool&)<br>
>> /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2056<br>
>>     #3 std::function<lldb_private::Error (bool&)>::operator()(bool&) const<br>
>> /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2464<br>
>>     #4 (anonymous namespace)::SelectIO(int, bool,<br>
>> std::function<lldb_private::Error (bool&)> const&,<br>
>> std::chrono::duration<long, std::ratio<1l, 1000000l> > const&)<br>
>> tools/lldb/source/Host/posix/PipePosix.cpp:118<br>
>>     #5 lldb_private::PipePosix::Write(void const*, unsigned long, unsigned<br>
>> long&) tools/lldb/source/Host/posix/PipePosix.cpp:411<br>
>>     #6 IOHandlerProcessSTDIO::Cancel()<br>
>> tools/lldb/source/Target/Process.cpp:5192<br>
>>     #7<br>
>> lldb_private::Debugger::PopIOHandler(std::shared_ptr<lldb_private::IOHandler><br>
>> const&) tools/lldb/source/Core/Debugger.cpp:1065<br>
>>     #8 lldb_private::Process::PopProcessIOHandler()<br>
>> tools/lldb/source/Target/Process.cpp:5291<br>
>>     #9<br>
>> lldb_private::Debugger::HandleProcessEvent(std::shared_ptr<lldb_private::Event><br>
>> const&) tools/lldb/source/Core/Debugger.cpp:1544<br>
>>     #10 lldb_private::Debugger::DefaultEventHandler()<br>
>> tools/lldb/source/Core/Debugger.cpp:1634<br>
>>     #11 lldb_private::Debugger::EventHandlerThread(void*)<br>
>> tools/lldb/source/Core/Debugger.cpp:1696<br>
>>     #12 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:81<br>
>><br>
>>   Previous write of size 8 at 0x7da0000080c0 by main thread:<br>
>>     #0 pipe2 <null>:0<br>
>>     #1 lldb_private::PipePosix::CreateNew(bool)<br>
>> tools/lldb/source/Host/posix/PipePosix.cpp:168<br>
>>     #2 IOHandlerProcessSTDIO::OpenPipes()<br>
>> tools/lldb/source/Target/Process.cpp:5078<br>
>>     #3 IOHandlerProcessSTDIO::Run()<br>
>> tools/lldb/source/Target/Process.cpp:5097<br>
>>     #4 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:907<br>
>>     #5 lldb_private::CommandInterpreter::RunCommandInterpreter(bool, bool,<br>
>> lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #6 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #7 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #8 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>>   Location is file descriptor 12 created by main thread at:<br>
>>     #0 pipe2 <null>:0<br>
>>     #1 lldb_private::PipePosix::CreateNew(bool)<br>
>> tools/lldb/source/Host/posix/PipePosix.cpp:168<br>
>>     #2 IOHandlerProcessSTDIO::OpenPipes()<br>
>> tools/lldb/source/Target/Process.cpp:5078<br>
>>     #3 IOHandlerProcessSTDIO::Run()<br>
>> tools/lldb/source/Target/Process.cpp:5097<br>
>>     #4 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:907<br>
>>     #5 lldb_private::CommandInterpreter::RunCommandInterpreter(bool, bool,<br>
>> lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #6 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #7 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #8 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>> ==================<br>
>> WARNING: ThreadSanitizer: data race (pid=64299)<br>
>>   Read of size 8 at 0x7d080001a5c8 by main thread:<br>
>>     #0 lldb_private::HostNativeThreadBase::GetSystemHandle() const<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:35<br>
>>     #1 lldb_private::HostThread::EqualsThread(unsigned long) const<br>
>> tools/lldb/source/Host/common/HostThread.cpp:77<br>
>>     #2 lldb_private::Process::GetRunLock()<br>
>> tools/lldb/source/Target/Process.cpp:6373<br>
>>     #3<br>
>> lldb_private::ExecutionContextRef::SetTargetPtr(lldb_private::Target*, bool)<br>
>> tools/lldb/source/Target/ExecutionContext.cpp:723<br>
>>     #4<br>
>> lldb_private::CommandInterpreter::UpdateExecutionContext(lldb_private::ExecutionContext*)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:2940<br>
>>     #5 lldb_private::CommandInterpreter::HandleCommand(char const*,<br>
>> lldb_private::LazyBool, lldb_private::CommandReturnObject&,<br>
>> lldb_private::ExecutionContext*, bool, bool)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:1668<br>
>>     #6<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:2997<br>
>>     #7 non-virtual thunk to<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:3076<br>
>>     #8 lldb_private::IOHandlerEditline::Run()<br>
>> tools/lldb/source/Core/IOHandler.cpp:729<br>
>>     #9 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:907<br>
>>     #10 lldb_private::CommandInterpreter::RunCommandInterpreter(bool,<br>
>> bool, lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #11 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #12 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #13 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>>   Previous write of size 8 at 0x7d080001a5c8 by thread T6:<br>
>>     #0 memset <null>:0<br>
>>     #1 lldb_private::HostNativeThreadBase::Reset()<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:54<br>
>>     #2 lldb_private::HostThread::Reset()<br>
>> tools/lldb/source/Host/common/HostThread.cpp:41<br>
>>     #3 lldb_private::Process::RunPrivateStateThread()<br>
>> tools/lldb/source/Target/Process.cpp:4604<br>
>>     #4 lldb_private::Process::PrivateStateThread(void*)<br>
>> tools/lldb/source/Target/Process.cpp:4505<br>
>>     #5 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:81<br>
>><br>
>> ==================<br>
>> WARNING: ThreadSanitizer: data race (pid=64299)<br>
>>   Write of size 4 at 0x7d680001c8e8 by main thread:<br>
>>     #0 lldb_private::Terminal::SetFileDescriptor(int)<br>
>> tools/lldb/include/lldb/Host/Terminal.h:46<br>
>>     #1 lldb_private::TerminalState::Save(int, bool)<br>
>> tools/lldb/source/Host/common/Terminal.cpp:144<br>
>>     #2 lldb_private::Debugger::SaveInputTerminalState()<br>
>> tools/lldb/source/Core/Debugger.cpp:825<br>
>>     #3 lldb::SBDebugger::SaveInputTerminalState()<br>
>> tools/lldb/source/API/SBDebugger.cpp:395<br>
>>     #4 sigtstp_handler(int) tools/lldb/tools/driver/Driver.cpp:1203<br>
>>     #5 __tsan::CallUserSignalHandler(__tsan::ThreadState*, bool, bool,<br>
>> int, my_siginfo_t*, void*) tsan_interceptors.o:0<br>
>>     #6 std::string::_Rep::_M_dispose(std::allocator<char> const&)<br>
>> /build/buildd/gcc-4.8-4.8.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.h:538<br>
>>     #7<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:2997<br>
>>     #8 non-virtual thunk to<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:3076<br>
>>     #9 lldb_private::IOHandlerEditline::Run()<br>
>> tools/lldb/source/Core/IOHandler.cpp:729<br>
>>     #10 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:907<br>
>>     #11 lldb_private::CommandInterpreter::RunCommandInterpreter(bool,<br>
>> bool, lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #12 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #13 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #14 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>>   Previous write of size 4 at 0x7d680001c8e8 by thread T2 (mutexes: write<br>
>> M159):<br>
>>     #0 lldb_private::Terminal::SetFileDescriptor(int)<br>
>> tools/lldb/include/lldb/Host/Terminal.h:46<br>
>>     #1 lldb_private::TerminalState::Save(int, bool)<br>
>> tools/lldb/source/Host/common/Terminal.cpp:144<br>
>>     #2 lldb_private::Debugger::SaveInputTerminalState()<br>
>> tools/lldb/source/Core/Debugger.cpp:825<br>
>>     #3 lldb::SBDebugger::SaveInputTerminalState()<br>
>> tools/lldb/source/API/SBDebugger.cpp:395<br>
>>     #4 sigtstp_handler(int) tools/lldb/tools/driver/Driver.cpp:1203<br>
>>     #5 __tsan::CallUserSignalHandler(__tsan::ThreadState*, bool, bool,<br>
>> int, my_siginfo_t*, void*) tsan_interceptors.o:0<br>
>>     #6 lldb_private::Condition::Wait(lldb_private::Mutex&,<br>
>> lldb_private::TimeValue const*, bool*)<br>
>> tools/lldb/source/Host/common/Condition.cpp:85<br>
>>     #7 lldb_private::Predicate<bool>::WaitForValueEqualTo(bool,<br>
>> lldb_private::TimeValue const*, bool*)<br>
>> tools/lldb/include/lldb/Host/Predicate.h:339<br>
>>     #8<br>
>> lldb_private::Listener::WaitForEventsInternal(lldb_private::TimeValue<br>
>> const*, lldb_private::Broadcaster*, lldb_private::ConstString const*,<br>
>> unsigned int, unsigned int, std::shared_ptr<lldb_private::Event>&)<br>
>> tools/lldb/source/Core/Listener.cpp:442<br>
>>     #9 lldb_private::Listener::WaitForEvent(lldb_private::TimeValue<br>
>> const*, std::shared_ptr<lldb_private::Event>&)<br>
>> tools/lldb/source/Core/Listener.cpp:492<br>
>>     #10 lldb_private::Debugger::DefaultEventHandler()<br>
>> tools/lldb/source/Core/Debugger.cpp:1623<br>
>>     #11 lldb_private::Debugger::EventHandlerThread(void*)<br>
>> tools/lldb/source/Core/Debugger.cpp:1696<br>
>>     #12 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:81<br>
>><br>
>> ==================<br>
>> WARNING: ThreadSanitizer: data race (pid=64299)<br>
>>   Write of size 4 at 0x7d680001c8ec by main thread:<br>
>>     #0 lldb_private::TerminalState::Save(int, bool)<br>
>> tools/lldb/source/Host/common/Terminal.cpp:148<br>
>>     #1 lldb_private::Debugger::SaveInputTerminalState()<br>
>> tools/lldb/source/Core/Debugger.cpp:825<br>
>>     #2 lldb::SBDebugger::SaveInputTerminalState()<br>
>> tools/lldb/source/API/SBDebugger.cpp:395<br>
>>     #3 sigtstp_handler(int) tools/lldb/tools/driver/Driver.cpp:1203<br>
>>     #4 __tsan::CallUserSignalHandler(__tsan::ThreadState*, bool, bool,<br>
>> int, my_siginfo_t*, void*) tsan_interceptors.o:0<br>
>>     #5 std::string::_Rep::_M_dispose(std::allocator<char> const&)<br>
>> /build/buildd/gcc-4.8-4.8.2/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.h:538<br>
>>     #6<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:2997<br>
>>     #7 non-virtual thunk to<br>
>> lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&,<br>
>> std::string&) tools/lldb/source/Interpreter/CommandInterpreter.cpp:3076<br>
>>     #8 lldb_private::IOHandlerEditline::Run()<br>
>> tools/lldb/source/Core/IOHandler.cpp:729<br>
>>     #9 lldb_private::Debugger::ExecuteIOHandlers()<br>
>> tools/lldb/source/Core/Debugger.cpp:907<br>
>>     #10 lldb_private::CommandInterpreter::RunCommandInterpreter(bool,<br>
>> bool, lldb_private::CommandInterpreterRunOptions&)<br>
>> tools/lldb/source/Interpreter/CommandInterpreter.cpp:3234<br>
>>     #11 lldb::SBDebugger::RunCommandInterpreter(bool, bool)<br>
>> tools/lldb/source/API/SBDebugger.cpp:980<br>
>>     #12 Driver::MainLoop() tools/lldb/tools/driver/Driver.cpp:1152<br>
>>     #13 main tools/lldb/tools/driver/Driver.cpp:1252<br>
>><br>
>>   Previous write of size 4 at 0x7d680001c8ec by thread T2 (mutexes: write<br>
>> M159):<br>
>>     #0 lldb_private::TerminalState::Save(int, bool)<br>
>> tools/lldb/source/Host/common/Terminal.cpp:148<br>
>>     #1 lldb_private::Debugger::SaveInputTerminalState()<br>
>> tools/lldb/source/Core/Debugger.cpp:825<br>
>>     #2 lldb::SBDebugger::SaveInputTerminalState()<br>
>> tools/lldb/source/API/SBDebugger.cpp:395<br>
>>     #3 sigtstp_handler(int) tools/lldb/tools/driver/Driver.cpp:1203<br>
>>     #4 __tsan::CallUserSignalHandler(__tsan::ThreadState*, bool, bool,<br>
>> int, my_siginfo_t*, void*) tsan_interceptors.o:0<br>
>>     #5 lldb_private::Condition::Wait(lldb_private::Mutex&,<br>
>> lldb_private::TimeValue const*, bool*)<br>
>> tools/lldb/source/Host/common/Condition.cpp:85<br>
>>     #6 lldb_private::Predicate<bool>::WaitForValueEqualTo(bool,<br>
>> lldb_private::TimeValue const*, bool*)<br>
>> tools/lldb/include/lldb/Host/Predicate.h:339<br>
>>     #7<br>
>> lldb_private::Listener::WaitForEventsInternal(lldb_private::TimeValue<br>
>> const*, lldb_private::Broadcaster*, lldb_private::ConstString const*,<br>
>> unsigned int, unsigned int, std::shared_ptr<lldb_private::Event>&)<br>
>> tools/lldb/source/Core/Listener.cpp:442<br>
>>     #8 lldb_private::Listener::WaitForEvent(lldb_private::TimeValue<br>
>> const*, std::shared_ptr<lldb_private::Event>&)<br>
>> tools/lldb/source/Core/Listener.cpp:492<br>
>>     #9 lldb_private::Debugger::DefaultEventHandler()<br>
>> tools/lldb/source/Core/Debugger.cpp:1623<br>
>>     #10 lldb_private::Debugger::EventHandlerThread(void*)<br>
>> tools/lldb/source/Core/Debugger.cpp:1696<br>
>>     #11 lldb_private::HostNativeThreadBase::ThreadCreateTrampoline(void*)<br>
>> tools/lldb/source/Host/common/HostNativeThreadBase.cpp:81<br>
>><br>
>><br>
>> -- Ryan Brown<br>
>><br>
>> On Mon, May 11, 2015 at 8:20 AM, Ed Maste <<a href="mailto:emaste@freebsd.org" target="_blank">emaste@freebsd.org</a>> wrote:<br>
>>><br>
>>> On 11 May 2015 at 10:21, Pavel Labath <<a href="mailto:labath@google.com" target="_blank">labath@google.com</a>> wrote:<br>
>>> ><br>
>>> > BTW, I've noticed that PushIOHandler does not lock<br>
>>> > m_input_reader_stack.GetMutex(), unlike PopIOHandler, and all other<br>
>>> > functions which deal with handlers. Is that intentional? I think it<br>
>>> > should lock the mutex as well.<br>
>>><br>
>>> A slight tangent here, but there's a lot of dubious thread behaviour<br>
>>> like this. One example I've run into is PR22611 - I see that if we set<br>
>>> a prompt that fits in libc++'s short string optimization (that is, no<br>
>>> more than 22 characters) it works fine, but as soon as the prompt is<br>
>>> 23 characters long we end up pointing at uninitialized memory;<br>
>>> presumably the race window is much larger in that case.<br>
>>><br>
>>> Unfortunately TSan isn't fully functional on FreeBSD at the moment, so<br>
>>> it's not that easy for me to find other cases like this with a<br>
>>> systematic approach. I recall there was an effort to run LLDB under<br>
>>> TSan on Linux some time ago, and that found a number of issues. Is<br>
>>> anyone on the Linux side interested in picking that up again?<br>
>>> _______________________________________________<br>
>>> lldb-dev mailing list<br>
>>> <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
>>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
>><br>
>><br>
>> _______________________________________________<br>
>> lldb-dev mailing list<br>
>> <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
><br>
><br>
> _______________________________________________<br>
> lldb-dev mailing list<br>
> <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
><br>
</blockquote></div>