mgorny created this revision. mgorny added reviewers: emaste, labath, krytarowski. mgorny requested review of this revision.
Explicitly copy dbregs to new threads to ensure that watchpoints are propagated properly. Fixes the test failure due to apparent kernel race between reporting a new thread and resuming main thread execution that makes implicit inheritance of dbregs unreliable. By copying them explicitly, we ensure that the new thread correctly respects watchpoints that were set after the thread was created but before it was reported. The code is copied from the NetBSD plugin and modernized to use llvm::Error. https://reviews.llvm.org/D91032 Files: lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.h lldb/test/API/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py
Index: lldb/test/API/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py =================================================================== --- lldb/test/API/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py +++ lldb/test/API/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py @@ -22,7 +22,6 @@ """Test that we can hit a watchpoint we set before starting another thread""" self.do_watchpoint_test("Before running the thread") - @expectedFailureAll(oslist=["freebsd"]) def test_watchpoint_after_thread_launch(self): """Test that we can hit a watchpoint we set after launching another thread""" self.do_watchpoint_test("After launching the thread") Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.h =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.h +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.h @@ -64,7 +64,7 @@ void SetRunning(); void SetStepping(); - Status CopyWatchpointsFrom(NativeThreadFreeBSD &source); + llvm::Error CopyWatchpointsFrom(NativeThreadFreeBSD &source); // Member Variables lldb::StateType m_state; Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeThreadFreeBSD.cpp @@ -273,3 +273,12 @@ return Status("Clearing hardware breakpoint failed."); } + +llvm::Error NativeThreadFreeBSD::CopyWatchpointsFrom(NativeThreadFreeBSD &source) { + llvm::Error s = GetRegisterContext().CopyHardwareWatchpointsFrom(source.GetRegisterContext()); + if (!s) { + m_watchpoint_index_map = source.m_watchpoint_index_map; + m_hw_break_index_map = source.m_hw_break_index_map; + } + return s; +} Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h @@ -50,6 +50,9 @@ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + llvm::Error + CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override; + private: // Private member types. enum { GPRegSet, FPRegSet, XSaveRegSet, DBRegSet }; Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp @@ -1169,4 +1169,19 @@ } } +llvm::Error NativeRegisterContextFreeBSD_x86_64::CopyHardwareWatchpointsFrom( + NativeRegisterContextFreeBSD &source) { + auto &r_source = static_cast<NativeRegisterContextFreeBSD_x86_64&>(source); + Status res = r_source.ReadRegisterSet(DBRegSet); + if (!res.Fail()) { + // copy dbregs only if any watchpoints were set + if ((r_source.m_dbr.dr[7] & 0xFF) == 0) + return llvm::Error::success(); + + m_dbr = r_source.m_dbr; + res = WriteRegisterSet(DBRegSet); + } + return res.ToError(); +} + #endif // defined(__x86_64__) Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h @@ -29,6 +29,8 @@ static NativeRegisterContextFreeBSD * CreateHostNativeRegisterContextFreeBSD(const ArchSpec &target_arch, NativeThreadProtocol &native_thread); + virtual llvm::Error + CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) = 0; protected: virtual NativeProcessFreeBSD &GetProcess(); Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp @@ -199,7 +199,16 @@ if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) { if (info.pl_flags & PL_FLAG_BORN) { LLDB_LOG(log, "monitoring new thread, tid = {0}", info.pl_lwpid); - AddThread(info.pl_lwpid); + NativeThreadFreeBSD& t = AddThread(info.pl_lwpid); + llvm::Error error = t.CopyWatchpointsFrom( + static_cast<NativeThreadFreeBSD &>(*GetCurrentThread())); + if (error) { + LLDB_LOG(log, + "failed to copy watchpoints to new thread {0}: {1}", + info.pl_lwpid, llvm::toString(std::move(error))); + SetState(StateType::eStateInvalid); + return; + } } else /*if (info.pl_flags & PL_FLAG_EXITED)*/ { LLDB_LOG(log, "thread exited, tid = {0}", info.pl_lwpid); RemoveThread(info.pl_lwpid);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits