diff options
author | Jim Ingham <jingham@apple.com> | 2013-07-11 23:20:35 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2013-07-11 23:20:35 +0000 |
commit | f1715ab270614776550e312ab4bc65f1d24f433a (patch) | |
tree | 6d032dfec892163adfb20361d368a1494b005f4e /lldb | |
parent | 64caeb7cd42c9e9beeca3afc5484817b83a65481 (diff) | |
download | bcm5719-llvm-f1715ab270614776550e312ab4bc65f1d24f433a.tar.gz bcm5719-llvm-f1715ab270614776550e312ab4bc65f1d24f433a.zip |
Get debugserver to call task_set_state to prime the control registers so that watchpoints
take for threads created while the program is running. Remove the testcase skips from TestConcurrentEvents.py,
since they all pass now, and fix TestWatchpointMultipleThreads.py - which should have caught this problem -
so it doesn't artificially break on new thread creation before the watchpoint triggers.
llvm.org/pr16566
<rdar://problem/14383244>
llvm-svn: 186132
Diffstat (limited to 'lldb')
14 files changed, 86 insertions, 197 deletions
diff --git a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme index 39343d6ff83..6860b549250 100644 --- a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme +++ b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme @@ -84,7 +84,7 @@ <LaunchAction selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "1" + launchStyle = "0" useCustomWorkingDirectory = "NO" customWorkingDirectory = "/Volumes/work/gclayton/Documents/devb/attach" buildConfiguration = "Debug" @@ -102,7 +102,7 @@ </BuildableProductRunnable> <CommandLineArguments> <CommandLineArgument - argument = "/private/tmp/a.out" + argument = "/Volumes/ThePlayground/Users/jingham/Projects/Sketch/build/Debug/Sketch.app" isEnabled = "YES"> </CommandLineArgument> </CommandLineArguments> diff --git a/lldb/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py b/lldb/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py index 583eb5db835..2218e4f3e1c 100644 --- a/lldb/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py +++ b/lldb/test/functionalities/thread/concurrent_events/TestConcurrentEvents.py @@ -37,7 +37,6 @@ class ConcurrentEventsTestCase(TestBase): self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_breakpoint_threads=100) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @unittest2.skipIf(TestBase.skipLongRunningTest(), "Skip this long running test") @dwarf_test def test_many_watchpoints_dwarf(self): @@ -88,21 +87,18 @@ class ConcurrentEventsTestCase(TestBase): # ## Tests for concurrent watchpoint and breakpoint # - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_watch_break_dwarf(self): """Test watchpoint and a breakpoint in multiple threads.""" self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_breakpoint_threads=1, num_watchpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_delay_watch_break_dwarf(self): """Test (1-second delay) watchpoint and a breakpoint in multiple threads.""" self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_breakpoint_threads=1, num_delay_watchpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_watch_break_dwarf(self): """Test watchpoint and a (1 second delay) breakpoint in multiple threads.""" @@ -112,21 +108,18 @@ class ConcurrentEventsTestCase(TestBase): # ## Tests for concurrent signal and watchpoint # - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_signal_watch_dwarf(self): """Test a watchpoint and a signal in multiple threads.""" self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_signal_threads=1, num_watchpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_delay_signal_watch_dwarf(self): """Test a watchpoint and a (1 second delay) signal in multiple threads.""" self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_delay_signal_threads=1, num_watchpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_signal_delay_watch_dwarf(self): """Test a (1 second delay) watchpoint and a signal in multiple threads.""" @@ -173,14 +166,12 @@ class ConcurrentEventsTestCase(TestBase): self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_breakpoint_threads=2, num_delay_signal_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_two_breakpoints_one_watchpoint_dwarf(self): """Test two threads that trigger a breakpoint and one watchpoint thread. """ self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_breakpoint_threads=2, num_watchpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_breakpoints_delayed_breakpoint_one_watchpoint_dwarf(self): """Test a breakpoint, a delayed breakpoint, and one watchpoint thread. """ @@ -192,14 +183,12 @@ class ConcurrentEventsTestCase(TestBase): # ## Tests for multiple watchpoint threads # - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_two_watchpoint_threads_dwarf(self): """Test two threads that trigger a watchpoint. """ self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_watchpoint_threads=2) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_watchpoint_with_delay_waychpoint_threads_dwarf(self): """Test two threads that trigger a watchpoint where one thread has a 1 second delay. """ @@ -207,21 +196,18 @@ class ConcurrentEventsTestCase(TestBase): self.do_thread_actions(num_watchpoint_threads=1, num_delay_watchpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_two_watchpoints_one_breakpoint_dwarf(self): """Test two threads that trigger a watchpoint and one breakpoint thread. """ self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_watchpoint_threads=2, num_breakpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_two_watchpoints_one_delay_breakpoint_dwarf(self): """Test two threads that trigger a watchpoint and one (1 second delay) breakpoint thread. """ self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_watchpoint_threads=2, num_delay_breakpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_watchpoint_delay_watchpoint_one_breakpoint_dwarf(self): """Test two threads that trigger a watchpoint (one with a 1 second delay) and one breakpoint thread. """ @@ -230,7 +216,6 @@ class ConcurrentEventsTestCase(TestBase): num_delay_watchpoint_threads=1, num_breakpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_two_watchpoints_one_signal_dwarf(self): """Test two threads that trigger a watchpoint and one signal thread. """ @@ -240,7 +225,6 @@ class ConcurrentEventsTestCase(TestBase): # ## Test for watchpoint, signal and breakpoint happening concurrently # - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @skipIfLinux # llvm.org/pr16575 -- LLDB crashes with assertion failure "Unexpected SIGTRAP code!" @dwarf_test def test_signal_watch_break_dwarf(self): @@ -250,7 +234,6 @@ class ConcurrentEventsTestCase(TestBase): num_watchpoint_threads=1, num_breakpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @skipIfLinux # llvm.org/pr16575 -- LLDB crashes with assertion failure "Unexpected SIGTRAP code!" @dwarf_test def test_signal_watch_break_dwarf(self): @@ -260,7 +243,6 @@ class ConcurrentEventsTestCase(TestBase): num_watchpoint_threads=5, num_breakpoint_threads=5) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_signal_watch_break_dwarf(self): """Test with 5 watchpoint and breakpoint threads.""" @@ -278,7 +260,6 @@ class ConcurrentEventsTestCase(TestBase): self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_crash_threads=1, num_breakpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_crash_with_watchpoint_dwarf(self): """ Test a thread that crashes while another thread hits a watchpoint.""" @@ -291,7 +272,6 @@ class ConcurrentEventsTestCase(TestBase): self.buildDwarf(dictionary=self.getBuildFlags()) self.do_thread_actions(num_crash_threads=1, num_signal_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @skipIfLinux # llvm.org/pr16575 -- LLDB crashes with assertion failure "Unexpected SIGTRAP code!" @dwarf_test def test_crash_with_watchpoint_breakpoint_signal_dwarf(self): @@ -302,7 +282,6 @@ class ConcurrentEventsTestCase(TestBase): num_signal_threads=1, num_watchpoint_threads=1) - @skipIfDarwin # llvm.org/pr16566 -- new threads do not respect watchpoints @dwarf_test def test_delayed_crash_with_breakpoint_watchpoint_dwarf(self): """ Test a thread with a delayed crash while other threads hit a watchpoint and a breakpoint. """ diff --git a/lldb/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py b/lldb/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py index f4fc0c43729..c498d405b76 100644 --- a/lldb/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py +++ b/lldb/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py @@ -52,7 +52,6 @@ class WatchpointForMultipleThreadsTestCase(TestBase): self.source = 'main.cpp' # Find the line number to break inside main(). self.first_stop = line_number(self.source, '// Set break point at this line') - self.thread_function = line_number(self.source, '// Break here in order to allow the thread') # Build dictionary to have unique executable names for each test method. self.exe_name = self.testMethodName self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name} @@ -65,10 +64,6 @@ class WatchpointForMultipleThreadsTestCase(TestBase): # Add a breakpoint to set a watchpoint when stopped on the breakpoint. lldbutil.run_break_set_by_file_and_line (self, None, self.first_stop, num_expected_locations=1) - # llvm.org/pr16566: LLDB requires a breakpoint to be hit before watchpoints are respected on a thread created after the watchpoing is set. - # Set this breakpoint to allow newly created thread to inherit the global watchpoint state. - lldbutil.run_break_set_by_file_and_line (self, None, self.thread_function, num_expected_locations=1) - # Run the program. self.runCmd("run", RUN_SUCCEEDED) @@ -90,18 +85,11 @@ class WatchpointForMultipleThreadsTestCase(TestBase): self.expect("watchpoint list -v", substrs = ['hit_count = 0']) - breakpoint_stops = 0 while True: self.runCmd("process continue") self.runCmd("thread list") - if "stop reason = breakpoint" in self.res.GetOutput(): - breakpoint_stops += 1 - # Since there are only three worker threads that could hit the breakpoint. - if breakpoint_stops > 3: - self.fail("Do not expect to break more than 3 times") - continue - elif "stop reason = watchpoint" in self.res.GetOutput(): + if "stop reason = watchpoint" in self.res.GetOutput(): # Good, we verified that the watchpoint works! self.runCmd("thread backtrace all") break @@ -121,9 +109,6 @@ class WatchpointForMultipleThreadsTestCase(TestBase): # Add a breakpoint to set a watchpoint when stopped on the breakpoint. lldbutil.run_break_set_by_file_and_line (self, None, self.first_stop, num_expected_locations=1) - # Set this breakpoint to allow newly created thread to inherit the global watchpoint state. - lldbutil.run_break_set_by_file_and_line (self, None, self.thread_function, num_expected_locations=1) - # Run the program. self.runCmd("run", RUN_SUCCEEDED) @@ -145,7 +130,6 @@ class WatchpointForMultipleThreadsTestCase(TestBase): self.expect("watchpoint list -v", substrs = ['hit_count = 0']) - breakpoint_stops = 0 watchpoint_stops = 0 while True: self.runCmd("process continue") @@ -155,16 +139,7 @@ class WatchpointForMultipleThreadsTestCase(TestBase): break self.runCmd("thread list") - if "stop reason = breakpoint" in self.res.GetOutput(): - self.runCmd("thread backtrace all") - breakpoint_stops += 1 - if self.TraceOn(): - print "breakpoint_stops=%d...." % breakpoint_stops - # Since there are only three worker threads that could hit the breakpoint. - if breakpoint_stops > 3: - self.fail("Do not expect to break more than 3 times") - continue - elif "stop reason = watchpoint" in self.res.GetOutput(): + if "stop reason = watchpoint" in self.res.GetOutput(): self.runCmd("thread backtrace all") watchpoint_stops += 1 if watchpoint_stops > 1: diff --git a/lldb/tools/darwin-threads/examine-threads.c b/lldb/tools/darwin-threads/examine-threads.c index 9e52bdf3060..291f1780996 100644 --- a/lldb/tools/darwin-threads/examine-threads.c +++ b/lldb/tools/darwin-threads/examine-threads.c @@ -293,7 +293,7 @@ main (int argc, char **argv) if (strcmp (argv[i], "-v") == 0) verbose = 1; if (strcmp (argv[i], "-r") == 0) - resume_when_done = 1; + resume_when_done++; i++; } } @@ -470,12 +470,16 @@ main (int argc, char **argv) nanosleep (rqtp, NULL); } while (do_loop); - kern_return_t err = task_resume (task); - if (err != KERN_SUCCESS) - printf ("Error resuming task: %d.", err); + while (resume_when_done > 0) + { + kern_return_t err = task_resume (task); + if (err != KERN_SUCCESS) + printf ("Error resuming task: %d.", err); + resume_when_done--; + } - vm_deallocate (mytask, (vm_address_t) task, sizeof (task_t)); - free ((void *) process_name); + vm_deallocate (mytask, (vm_address_t) task, sizeof (task_t)); + free ((void *) process_name); return 0; } diff --git a/lldb/tools/debugserver/source/DNBArch.h b/lldb/tools/debugserver/source/DNBArch.h index 08e7042f43f..1c5c5b2db6f 100644 --- a/lldb/tools/debugserver/source/DNBArch.h +++ b/lldb/tools/debugserver/source/DNBArch.h @@ -76,10 +76,9 @@ public: virtual uint32_t NumSupportedHardwareBreakpoints() { return 0; } virtual uint32_t NumSupportedHardwareWatchpoints() { return 0; } virtual uint32_t EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size) { return INVALID_NUB_HW_INDEX; } - virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) { return INVALID_NUB_HW_INDEX; } - virtual void HardwareWatchpointStateChanged () { ; } + virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task) { return INVALID_NUB_HW_INDEX; } virtual bool DisableHardwareBreakpoint (uint32_t hw_index) { return false; } - virtual bool DisableHardwareWatchpoint (uint32_t hw_index) { return false; } + virtual bool DisableHardwareWatchpoint (uint32_t hw_index, bool also_set_on_task) { return false; } virtual uint32_t GetHardwareWatchpointHit() { return INVALID_NUB_HW_INDEX; } virtual bool StepNotComplete () { return false; } diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp index 5a8b79a19e9..c11d2c2ca82 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp @@ -625,20 +625,13 @@ MachThread::EnableHardwareBreakpoint (const DNBBreakpoint *bp) } uint32_t -MachThread::EnableHardwareWatchpoint (const DNBBreakpoint *wp) +MachThread::EnableHardwareWatchpoint (const DNBBreakpoint *wp, bool also_set_on_task) { if (wp != NULL && wp->IsWatchpoint()) - return m_arch_ap->EnableHardwareWatchpoint(wp->Address(), wp->ByteSize(), wp->WatchpointRead(), wp->WatchpointWrite()); + return m_arch_ap->EnableHardwareWatchpoint(wp->Address(), wp->ByteSize(), wp->WatchpointRead(), wp->WatchpointWrite(), also_set_on_task); return INVALID_NUB_HW_INDEX; } -// Provide a chance to update the global view of the hardware watchpoint state. -void -MachThread::HardwareWatchpointStateChanged () -{ - m_arch_ap->HardwareWatchpointStateChanged(); -} - bool MachThread::RollbackTransForHWP() { @@ -660,10 +653,10 @@ MachThread::DisableHardwareBreakpoint (const DNBBreakpoint *bp) } bool -MachThread::DisableHardwareWatchpoint (const DNBBreakpoint *wp) +MachThread::DisableHardwareWatchpoint (const DNBBreakpoint *wp, bool also_set_on_task) { if (wp != NULL && wp->IsHardware()) - return m_arch_ap->DisableHardwareWatchpoint(wp->GetHardwareIndex()); + return m_arch_ap->DisableHardwareWatchpoint(wp->GetHardwareIndex(), also_set_on_task); return false; } diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.h b/lldb/tools/debugserver/source/MacOSX/MachThread.h index bf96e68bc6c..7e16d49b78c 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachThread.h +++ b/lldb/tools/debugserver/source/MacOSX/MachThread.h @@ -64,9 +64,9 @@ public: DNBBreakpoint * CurrentBreakpoint(); uint32_t EnableHardwareBreakpoint (const DNBBreakpoint *breakpoint); - uint32_t EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint); + uint32_t EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint, bool also_set_on_task); bool DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint); - bool DisableHardwareWatchpoint (const DNBBreakpoint *watchpoint); + bool DisableHardwareWatchpoint (const DNBBreakpoint *watchpoint, bool also_set_on_task); uint32_t NumSupportedHardwareWatchpoints () const; bool RollbackTransForHWP(); bool FinishTransForHWP(); @@ -138,7 +138,6 @@ protected: private: friend class MachThreadList; - void HardwareWatchpointStateChanged(); // Provide a chance to update the global view of the hardware watchpoint state }; typedef std::shared_ptr<MachThread> MachThreadSP; diff --git a/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp b/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp index f549b4707d9..b5ce58d3438 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp @@ -528,23 +528,24 @@ MachThreadList::EnableHardwareWatchpoint (const DNBBreakpoint* wp) const { PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); const uint32_t num_threads = m_threads.size(); + // On Mac OS X we have to prime the control registers for new threads. We do this + // using the control register data for the first thread, for lack of a better way of choosing. + bool also_set_on_task = true; for (uint32_t idx = 0; idx < num_threads; ++idx) - { - if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp)) == INVALID_NUB_HW_INDEX) + { + if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp, also_set_on_task)) == INVALID_NUB_HW_INDEX) { // We know that idx failed for some reason. Let's rollback the transaction for [0, idx). for (uint32_t i = 0; i < idx; ++i) m_threads[i]->RollbackTransForHWP(); return INVALID_NUB_HW_INDEX; } + also_set_on_task = false; } // Notify each thread to commit the pending transaction. for (uint32_t idx = 0; idx < num_threads; ++idx) m_threads[idx]->FinishTransForHWP(); - // Use an arbitrary thread to signal the completion of our transaction. - if (num_threads) - m_threads[0]->HardwareWatchpointStateChanged(); } return hw_index; } @@ -556,23 +557,25 @@ MachThreadList::DisableHardwareWatchpoint (const DNBBreakpoint* wp) const { PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); const uint32_t num_threads = m_threads.size(); + + // On Mac OS X we have to prime the control registers for new threads. We do this + // using the control register data for the first thread, for lack of a better way of choosing. + bool also_set_on_task = true; for (uint32_t idx = 0; idx < num_threads; ++idx) { - if (!m_threads[idx]->DisableHardwareWatchpoint(wp)) + if (!m_threads[idx]->DisableHardwareWatchpoint(wp, also_set_on_task)) { // We know that idx failed for some reason. Let's rollback the transaction for [0, idx). for (uint32_t i = 0; i < idx; ++i) m_threads[i]->RollbackTransForHWP(); return false; } + also_set_on_task = false; } // Notify each thread to commit the pending transaction. for (uint32_t idx = 0; idx < num_threads; ++idx) m_threads[idx]->FinishTransForHWP(); - // Use an arbitrary thread to signal the completion of our transaction. - if (num_threads) - m_threads[0]->HardwareWatchpointStateChanged(); return true; } return false; diff --git a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp index 7a0ac7b1091..5393fbf2778 100644 --- a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp +++ b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp @@ -118,15 +118,6 @@ DNBArchProtocol * DNBArchMachARM::Create (MachThread *thread) { DNBArchMachARM *obj = new DNBArchMachARM (thread); - - // When new thread comes along, it tries to inherit from the global debug state, if it is valid. - if (Valid_Global_Debug_State) - { - obj->m_state.dbg = Global_Debug_State; - kern_return_t kret = obj->SetDBGState(); - DNBLogThreadedIf(LOG_WATCHPOINTS, - "DNBArchMachARM::Create() Inherit and SetDBGState() => 0x%8.8x.", kret); - } return obj; } @@ -323,10 +314,16 @@ DNBArchMachARM::SetEXCState() } kern_return_t -DNBArchMachARM::SetDBGState() +DNBArchMachARM::SetDBGState(bool also_set_on_task) { int set = e_regSetDBG; kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT); + if (also_set_on_task) + { + kern_return_t task_kret = ::task_set_state (m_thread->Process()->Task().TaskPort(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT); + if (task_kret != KERN_SUCCESS) + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::SetDBGState failed to set debug control register state: 0x%8.8x.", kret); + } m_state.SetError(set, Write, kret); // Set the current write error for this register set m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently return kret; // Return the error code @@ -579,7 +576,7 @@ DNBArchMachARM::EnableHardwareSingleStep (bool enable) m_state.dbg = m_dbg_save; } - return SetDBGState(); + return SetDBGState(false); } // return 1 if bit "BIT" is set in "value" @@ -832,7 +829,7 @@ DNBArchMachARM::EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size) m_state.dbg.__bcr[i]); } - kret = SetDBGState(); + kret = SetDBGState(false); DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint() SetDBGState() => 0x%8.8x.", kret); if (kret == KERN_SUCCESS) @@ -865,7 +862,7 @@ DNBArchMachARM::DisableHardwareBreakpoint (uint32_t hw_index) hw_index, m_state.dbg.__bcr[hw_index]); - kret = SetDBGState(); + kret = SetDBGState(false); if (kret == KERN_SUCCESS) return true; @@ -879,7 +876,7 @@ DNBArchMachARM::DisableHardwareBreakpoint (uint32_t hw_index) static uint32_t LoHi[16] = { 0 }; uint32_t -DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) +DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task) { DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(addr = 0x%8.8llx, size = %llu, read = %u, write = %u)", (uint64_t)addr, (uint64_t)size, read, write); @@ -942,7 +939,7 @@ DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool return INVALID_NUB_HW_INDEX; // Read the debug state - kern_return_t kret = GetDBGState(false); + kern_return_t kret = GetDBGState(true); if (kret == KERN_SUCCESS) { @@ -972,7 +969,7 @@ DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() adding watchpoint on address 0x%llx with control register value 0x%x", (uint64_t) m_state.dbg.__wvr[i], (uint32_t) m_state.dbg.__wcr[i]); - kret = SetDBGState(); + kret = SetDBGState(also_set_on_task); //DumpDBGState(m_state.dbg); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); @@ -1013,7 +1010,7 @@ DNBArchMachARM::EnableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate) hw_index, m_state.dbg.__wcr[hw_index]); - kret = SetDBGState(); + kret = SetDBGState(false); return (kret == KERN_SUCCESS); } @@ -1053,20 +1050,6 @@ DNBArchMachARM::DisableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate) return (kret == KERN_SUCCESS); } -// {0} -> __bvr[16], {0} -> __bcr[16], {0} --> __wvr[16], {0} -> __wcr{16} -DNBArchMachARM::DBG DNBArchMachARM::Global_Debug_State = {{0},{0},{0},{0}}; -bool DNBArchMachARM::Valid_Global_Debug_State = false; - -// Use this callback from MachThread, which in turn was called from MachThreadList, to update -// the global view of the hardware watchpoint state, so that when new thread comes along, they -// get to inherit the existing hardware watchpoint state. -void -DNBArchMachARM::HardwareWatchpointStateChanged () -{ - Global_Debug_State = m_state.dbg; - Valid_Global_Debug_State = true; -} - // Returns -1 if the trailing bit patterns are not one of: // { 0b???1, 0b??10, 0b?100, 0b1000 }. static inline @@ -1753,11 +1736,11 @@ DNBArchMachARM::SetRegisterState(int set) case e_regSetALL: return SetGPRState() | SetVFPState() | SetEXCState() | - SetDBGState(); + SetDBGState(false); case e_regSetGPR: return SetGPRState(); case e_regSetVFP: return SetVFPState(); case e_regSetEXC: return SetEXCState(); - case e_regSetDBG: return SetDBGState(); + case e_regSetDBG: return SetDBGState(false); default: break; } return KERN_INVALID_ARGUMENT; diff --git a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h index c13b607c2e9..ffb732a5991 100644 --- a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h +++ b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h @@ -71,13 +71,12 @@ public: virtual uint32_t NumSupportedHardwareBreakpoints(); virtual uint32_t NumSupportedHardwareWatchpoints(); virtual uint32_t EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size); - virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); + virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task); virtual bool DisableHardwareBreakpoint (uint32_t hw_break_index); - virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); + virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index, bool also_set_on_task); virtual bool EnableHardwareWatchpoint0 (uint32_t hw_break_index, bool Delegate); virtual bool DisableHardwareWatchpoint0 (uint32_t hw_break_index, bool Delegate); virtual bool StepNotComplete (); - virtual void HardwareWatchpointStateChanged (); virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr); typedef arm_debug_state_t DBG; @@ -135,10 +134,6 @@ protected: EXC exc; }; - // See also HardwareWatchpointStateChanged() which updates this class-wide variable. - static DBG Global_Debug_State; - static bool Valid_Global_Debug_State; - struct State { Context context; @@ -230,7 +225,7 @@ protected: kern_return_t SetGPRState (); kern_return_t SetVFPState (); kern_return_t SetEXCState (); - kern_return_t SetDBGState (); + kern_return_t SetDBGState (bool also_set_on_task); // Helper functions for watchpoint implementaions. static void ClearWatchpointOccurred(); diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp index 4376e80b653..885f6d0d54d 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp @@ -556,9 +556,16 @@ DNBArchImplI386::GetDBGState(bool force) } kern_return_t -DNBArchImplI386::SetDBGState() +DNBArchImplI386::SetDBGState(bool also_set_on_task) { m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG)); + if (also_set_on_task) + { + kern_return_t kret = ::task_set_state(m_thread->Process()->Task().TaskPort(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG); + if (kret != KERN_SUCCESS) + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::SetDBGState failed to set debug control register state: 0x%8.8x.", kret); + + } return m_state.GetError(e_regSetDBG, Write); } @@ -588,7 +595,7 @@ DNBArchImplI386::ThreadWillResume() if (need_reset) { ClearWatchpointHits(debug_state); - kret = SetDBGState(); + kret = SetDBGState(false); DNBLogThreadedIf(LOG_WATCHPOINTS,"DNBArchImplI386::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); } } @@ -854,7 +861,7 @@ DNBArchImplI386::RollbackTransForHWP() if (m_2pc_trans_state != Trans_Pending) DNBLogError ("%s inconsistent state detected, expected %d, got: %d", __FUNCTION__, Trans_Pending, m_2pc_trans_state); m_2pc_trans_state = Trans_Rolled_Back; - kern_return_t kret = SetDBGState(); + kern_return_t kret = SetDBGState(false); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", kret); if (kret == KERN_SUCCESS) @@ -875,7 +882,7 @@ DNBArchImplI386::GetDBGCheckpoint() } uint32_t -DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) +DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task) { DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::EnableHardwareWatchpoint(addr = 0x%llx, size = %llu, read = %u, write = %u)", (uint64_t)addr, (uint64_t)size, read, write); @@ -912,7 +919,7 @@ DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, boo // Modify our local copy of the debug state, first. SetWatchpoint(debug_state, i, addr, size, read, write); // Now set the watch point in the inferior. - kret = SetDBGState(); + kret = SetDBGState(also_set_on_task); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); if (kret == KERN_SUCCESS) @@ -929,7 +936,7 @@ DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, boo } bool -DNBArchImplI386::DisableHardwareWatchpoint (uint32_t hw_index) +DNBArchImplI386::DisableHardwareWatchpoint (uint32_t hw_index, bool also_set_on_task) { kern_return_t kret = GetDBGState(false); @@ -944,7 +951,7 @@ DNBArchImplI386::DisableHardwareWatchpoint (uint32_t hw_index) // Modify our local copy of the debug state, first. ClearWatchpoint(debug_state, hw_index); // Now disable the watch point in the inferior. - kret = SetDBGState(); + kret = SetDBGState(also_set_on_task); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::DisableHardwareWatchpoint( %u )", hw_index); @@ -957,19 +964,6 @@ DNBArchImplI386::DisableHardwareWatchpoint (uint32_t hw_index) return false; } -DNBArchImplI386::DBG DNBArchImplI386::Global_Debug_State = {0,0,0,0,0,0,0,0}; -bool DNBArchImplI386::Valid_Global_Debug_State = false; - -// Use this callback from MachThread, which in turn was called from MachThreadList, to update -// the global view of the hardware watchpoint state, so that when new thread comes along, they -// get to inherit the existing hardware watchpoint state. -void -DNBArchImplI386::HardwareWatchpointStateChanged () -{ - Global_Debug_State = m_state.context.dbg; - Valid_Global_Debug_State = true; -} - // Iterate through the debug status register; return the index of the first hit. uint32_t DNBArchImplI386::GetHardwareWatchpointHit(nub_addr_t &addr) @@ -1228,15 +1222,6 @@ DNBArchProtocol * DNBArchImplI386::Create (MachThread *thread) { DNBArchImplI386 *obj = new DNBArchImplI386 (thread); - - // When new thread comes along, it tries to inherit from the global debug state, if it is valid. - if (Valid_Global_Debug_State) - { - obj->m_state.context.dbg = Global_Debug_State; - kern_return_t kret = obj->SetDBGState(); - DNBLogThreadedIf(LOG_WATCHPOINTS, - "DNBArchImplX86_64::Create() Inherit and SetDBGState() => 0x%8.8x.", kret); - } return obj; } diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h index 85cdcd3dde9..6cd78d18d99 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h @@ -54,9 +54,8 @@ public: virtual bool NotifyException(MachException::Data& exc); virtual uint32_t NumSupportedHardwareWatchpoints(); - virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); - virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); - virtual void HardwareWatchpointStateChanged (); + virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task); + virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index, bool also_set_on_task); virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr); protected: @@ -119,10 +118,6 @@ protected: DBG dbg; }; - // See also HardwareWatchpointStateChanged() which updates this class-wide variable. - static DBG Global_Debug_State; - static bool Valid_Global_Debug_State; - struct State { Context context; @@ -214,7 +209,7 @@ protected: kern_return_t SetGPRState (); kern_return_t SetFPUState (); kern_return_t SetEXCState (); - kern_return_t SetDBGState (); + kern_return_t SetDBGState (bool also_set_on_task); static DNBArchProtocol * Create (MachThread *thread); diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp index aff76d881f1..7c2f6ac8066 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp @@ -511,9 +511,15 @@ DNBArchImplX86_64::GetDBGState(bool force) } kern_return_t -DNBArchImplX86_64::SetDBGState() +DNBArchImplX86_64::SetDBGState(bool also_set_on_task) { m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG)); + if (also_set_on_task) + { + kern_return_t kret = ::task_set_state(m_thread->Process()->Task().TaskPort(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG); + if (kret != KERN_SUCCESS) + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::SetDBGState failed to set debug control register state: 0x%8.8x.", kret); + } return m_state.GetError(e_regSetDBG, Write); } @@ -543,7 +549,7 @@ DNBArchImplX86_64::ThreadWillResume() if (need_reset) { ClearWatchpointHits(debug_state); - kret = SetDBGState(); + kret = SetDBGState(false); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); } } @@ -808,7 +814,7 @@ DNBArchImplX86_64::RollbackTransForHWP() if (m_2pc_trans_state != Trans_Pending) DNBLogError ("%s inconsistent state detected, expected %d, got: %d", __FUNCTION__, Trans_Pending, m_2pc_trans_state); m_2pc_trans_state = Trans_Rolled_Back; - kern_return_t kret = SetDBGState(); + kern_return_t kret = SetDBGState(false); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", kret); if (kret == KERN_SUCCESS) @@ -829,7 +835,7 @@ DNBArchImplX86_64::GetDBGCheckpoint() } uint32_t -DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) +DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task) { DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::EnableHardwareWatchpoint(addr = 0x%llx, size = %llu, read = %u, write = %u)", (uint64_t)addr, (uint64_t)size, read, write); @@ -866,7 +872,7 @@ DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, b // Modify our local copy of the debug state, first. SetWatchpoint(debug_state, i, addr, size, read, write); // Now set the watch point in the inferior. - kret = SetDBGState(); + kret = SetDBGState(also_set_on_task); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); if (kret == KERN_SUCCESS) @@ -883,7 +889,7 @@ DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, b } bool -DNBArchImplX86_64::DisableHardwareWatchpoint (uint32_t hw_index) +DNBArchImplX86_64::DisableHardwareWatchpoint (uint32_t hw_index, bool also_set_on_task) { kern_return_t kret = GetDBGState(false); @@ -898,7 +904,7 @@ DNBArchImplX86_64::DisableHardwareWatchpoint (uint32_t hw_index) // Modify our local copy of the debug state, first. ClearWatchpoint(debug_state, hw_index); // Now disable the watch point in the inferior. - kret = SetDBGState(); + kret = SetDBGState(also_set_on_task); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::DisableHardwareWatchpoint( %u )", hw_index); @@ -911,19 +917,6 @@ DNBArchImplX86_64::DisableHardwareWatchpoint (uint32_t hw_index) return false; } -DNBArchImplX86_64::DBG DNBArchImplX86_64::Global_Debug_State = {0,0,0,0,0,0,0,0}; -bool DNBArchImplX86_64::Valid_Global_Debug_State = false; - -// Use this callback from MachThread, which in turn was called from MachThreadList, to update -// the global view of the hardware watchpoint state, so that when new thread comes along, they -// get to inherit the existing hardware watchpoint state. -void -DNBArchImplX86_64::HardwareWatchpointStateChanged () -{ - Global_Debug_State = m_state.context.dbg; - Valid_Global_Debug_State = true; -} - // Iterate through the debug status register; return the index of the first hit. uint32_t DNBArchImplX86_64::GetHardwareWatchpointHit(nub_addr_t &addr) @@ -1556,15 +1549,6 @@ DNBArchProtocol * DNBArchImplX86_64::Create (MachThread *thread) { DNBArchImplX86_64 *obj = new DNBArchImplX86_64 (thread); - - // When new thread comes along, it tries to inherit from the global debug state, if it is valid. - if (Valid_Global_Debug_State) - { - obj->m_state.context.dbg = Global_Debug_State; - kern_return_t kret = obj->SetDBGState(); - DNBLogThreadedIf(LOG_WATCHPOINTS, - "DNBArchImplX86_64::Create() Inherit and SetDBGState() => 0x%8.8x.", kret); - } return obj; } diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h index 4d1ded90c61..7ff8d9c47c4 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h @@ -53,9 +53,8 @@ public: virtual bool NotifyException(MachException::Data& exc); virtual uint32_t NumSupportedHardwareWatchpoints(); - virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); - virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); - virtual void HardwareWatchpointStateChanged (); + virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task); + virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index, bool also_set_on_task); virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr); protected: @@ -118,10 +117,6 @@ protected: DBG dbg; }; - // See also HardwareWatchpointStateChanged() which updates this class-wide variable. - static DBG Global_Debug_State; - static bool Valid_Global_Debug_State; - struct State { Context context; @@ -221,7 +216,7 @@ protected: kern_return_t SetGPRState (); kern_return_t SetFPUState (); kern_return_t SetEXCState (); - kern_return_t SetDBGState (); + kern_return_t SetDBGState (bool also_set_on_task); static DNBArchProtocol * Create (MachThread *thread); |