From c2c8ca1ce3de4d9d4013ab6da5d759f59515ec78 Mon Sep 17 00:00:00 2001 From: Abhishek Aggarwal Date: Mon, 1 Feb 2016 09:01:42 +0000 Subject: [PATCH] Set correct ThreadStopInfo in case of trace event Summary: - The patch solves Bug 23478 and Bug 19311. Resolving Bug 23478 also resolves Bug 23039. Correct ThreadStopInfo is set for Linux and FreeBSD platforms. - Summary: When a trace event is reported, we need to check whether the trace event lands at a breakpoint site. If it lands at a breakpoint site then set the thread's StopInfo with the reason 'breakpoint'. Else, set the reason to be 'Trace'. Change-Id: I0af9765e782fd74bc0cead41548486009f8abb87 Signed-off-by: Abhishek Aggarwal Reviewers: jingham, emaste, lldb-commits, clayborg, ovyalov Subscribers: emaste Differential Revision: http://reviews.llvm.org/D16720 llvm-svn: 259344 --- .../TestConsecutiveBreakpoints.py | 1 - .../TestDynamicValueChildCount.py | 3 -- .../Plugins/Process/FreeBSD/FreeBSDThread.cpp | 47 +++++++++++++++++----- .../Process/gdb-remote/ProcessGDBRemote.cpp | 22 +++++++++- 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py index 61379bd..7f5e5ad 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py @@ -15,7 +15,6 @@ class ConsecutiveBreakpointsTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) - @expectedFailureAll("llvm.org/pr23478", oslist = not_in(["macosx"])) def test (self): self.build () self.consecutive_breakpoints_tests() diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py b/lldb/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py index ac03999..025b546 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/dynamic_value_child_count/TestDynamicValueChildCount.py @@ -31,10 +31,7 @@ class DynamicValueChildCountTestCase(TestBase): self.main_sixth_call_line = line_number('pass-to-base.cpp', '// Break here and check b has 0 children again') - @expectedFailureLinux("llvm.org/pr23039") - @expectedFailureFreeBSD("llvm.org/pr19311") # continue at a breakpoint does not work @expectedFailureWindows("llvm.org/pr24663") - @expectedFailurei386("to be figured out") @add_test_categories(['pyapi']) def test_get_dynamic_vals(self): """Test fetching C++ dynamic values from pointers & references.""" diff --git a/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index 2b29244..46cf2bd 100644 --- a/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -558,22 +558,49 @@ FreeBSDThread::WatchNotify(const ProcessMessage &message) void FreeBSDThread::TraceNotify(const ProcessMessage &message) { - POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); - if (reg_ctx) + Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); + + // Try to resolve the breakpoint object corresponding to the current PC. + assert(GetRegisterContext()); + lldb::addr_t pc = GetRegisterContext()->GetPC(); + if (log) + log->Printf ("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); + lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc)); + + // If the current pc is a breakpoint site then set the StopInfo to Breakpoint. + // Otherwise, set the StopInfo to Watchpoint or Trace. + if (bp_site) { - uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); - uint32_t wp_idx; - for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) + lldb::break_id_t bp_id = bp_site->GetID(); + // If we have an operating system plug-in, we might have set a thread specific breakpoint using the + // operating system thread ID, so we can't make any assumptions about the thread ID so we must always + // report the breakpoint regardless of the thread. + if (bp_site->ValidForThisThread(this) || GetProcess()->GetOperatingSystem () != NULL) + SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id)); + else { - if (reg_ctx->IsWatchpointHit(wp_idx)) + const bool should_stop = false; + SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id, should_stop)); + } + } + else + { + POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); + if (reg_ctx) + { + uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); + uint32_t wp_idx; + for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) { - WatchNotify(message); - return; + if (reg_ctx->IsWatchpointHit(wp_idx)) + { + WatchNotify(message); + return; + } } } + SetStopInfo (StopInfo::CreateStopReasonToTrace(*this)); } - - SetStopInfo (StopInfo::CreateStopReasonToTrace(*this)); } void diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 856ea35..21dad4e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -2001,7 +2001,27 @@ ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid, { if (reason.compare("trace") == 0) { - thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp)); + addr_t pc = thread_sp->GetRegisterContext()->GetPC(); + lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc); + + // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint + // Otherwise, it will be set to Trace. + if (bp_site_sp) + { + // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread, + // we can just report no reason. + if (bp_site_sp->ValidForThisThread (thread_sp.get())) + { + thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID())); + } + else + { + StopInfoSP invalid_stop_info_sp; + thread_sp->SetStopInfo (invalid_stop_info_sp); + } + } + else + thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp)); handled = true; } else if (reason.compare("breakpoint") == 0) -- 2.7.4