[Lldb-commits] [lldb] r371166 - [Windows] Add support of watchpoints to `ProcessWindows`

Aleksandr Urakov via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 5 22:37:04 PDT 2019


Author: aleksandr.urakov
Date: Thu Sep  5 22:37:03 2019
New Revision: 371166

URL: http://llvm.org/viewvc/llvm-project?rev=371166&view=rev
Log:
[Windows] Add support of watchpoints to `ProcessWindows`

Summary:
This patch adds support of watchpoints to the old `ProcessWindows` plugin.

The `ProcessWindows` plugin uses the `RegisterContext` to set and reset
watchpoints. The `RegisterContext` has some interface to access watchpoints,
but it is very limited (e.g. it is impossible to retrieve the last triggered
watchpoint with it), that's why I have implemented a slightly different
interface in the `RegisterContextWindows`. Moreover, I have made the
`ProcessWindows` plugin responsible for search of a vacant watchpoint slot,
because watchpoints exist per-process (not per-thread), then we can place
the same watchpoint in the same slot in different threads. With this scheme
threads don't need to have their own watchpoint lists, and it simplifies
identifying of the last triggered watchpoint.

Reviewers: asmith, stella.stamenova, amccarth

Reviewed By: amccarth

Subscribers: labath, zturner, leonid.mashinskiy, abidh, JDevlieghere, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D67168

Modified:
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchlocation/TestWatchLocation.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchpoint/TestMyFirstWatchpoint.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_hits/TestMultipleHits.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandLLDB.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/condition/TestWatchpointConditionCmd.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_disable/TestWatchpointDisable.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_events/TestWatchpointEvents.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_on_vectors/TestValueOfVectorVariable.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_set_command/TestWatchLocationWithWatchSet.py
    lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_size/TestWatchpointSizes.py
    lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py
    lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
    lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py
    lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
    lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
    lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessDebugger.h
    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h
    lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
    lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchlocation/TestWatchLocation.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchlocation/TestWatchLocation.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchlocation/TestWatchLocation.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchlocation/TestWatchLocation.py Thu Sep  5 22:37:03 2019
@@ -31,9 +31,6 @@ class HelloWatchLocationTestCase(TestBas
         self.exe_name = self.testMethodName
         self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Most of the MIPS boards provide only one H/W watchpoints, and S/W
     # watchpoints are not supported yet
     @expectedFailureAll(triple=re.compile('^mips'))

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchpoint/TestMyFirstWatchpoint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchpoint/TestMyFirstWatchpoint.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchpoint/TestMyFirstWatchpoint.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/hello_watchpoint/TestMyFirstWatchpoint.py Thu Sep  5 22:37:03 2019
@@ -29,9 +29,6 @@ class HelloWatchpointTestCase(TestBase):
         self.exe_name = self.getBuildArtifact('a.out')
         self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @add_test_categories(["basic_process"])
     def test_hello_watchpoint_using_watchpoint_set(self):
         """Test a simple sequence of watchpoint creation and watchpoint hit."""

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_hits/TestMultipleHits.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_hits/TestMultipleHits.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_hits/TestMultipleHits.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_hits/TestMultipleHits.py Thu Sep  5 22:37:03 2019
@@ -16,9 +16,6 @@ class MultipleHitsTestCase(TestBase):
     mydir = TestBase.compute_mydir(__file__)
     NO_DEBUG_INFO_TESTCASE = True
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @skipIf(bugnumber="llvm.org/pr30758", oslist=["linux"], archs=["arm", "aarch64", "powerpc64le"])
     @skipIfwatchOS
     def test(self):

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py Thu Sep  5 22:37:03 2019
@@ -18,17 +18,11 @@ class WatchpointForMultipleThreadsTestCa
     NO_DEBUG_INFO_TESTCASE = True
     main_spec = lldb.SBFileSpec("main.cpp", False)
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @expectedFailureNetBSD
     def test_watchpoint_before_thread_start(self):
         """Test that we can hit a watchpoint we set before starting another thread"""
         self.do_watchpoint_test("Before running the thread")
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @expectedFailureNetBSD
     def test_watchpoint_after_thread_start(self):
         """Test that we can hit a watchpoint we set after starting another thread"""
@@ -66,9 +60,6 @@ class WatchpointForMultipleThreadsTestCa
         self.expect("watchpoint list -v",
                     substrs=['hit_count = 1'])
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     def test_watchpoint_multiple_threads_wp_set_and_then_delete(self):
         """Test that lldb watchpoint works for multiple threads, and after the watchpoint is deleted, the watchpoint event should no longer fires."""
         self.build()

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py Thu Sep  5 22:37:03 2019
@@ -19,9 +19,6 @@ class TestStepOverWatchpoint(TestBase):
             'aarch64',
             'arm'],
         bugnumber="llvm.org/pr26031")
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     @expectedFailureAll(oslist=["ios", "watchos", "tvos", "bridgeos"], bugnumber="<rdar://problem/34027183>")  # watchpoint tests aren't working on arm64

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/TestWatchpointCommands.py Thu Sep  5 22:37:03 2019
@@ -34,9 +34,6 @@ class WatchpointCommandsTestCase(TestBas
         self.exe_name = self.testMethodName
         self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_rw_watchpoint(self):
@@ -105,9 +102,6 @@ class WatchpointCommandsTestCase(TestBas
         self.expect("watchpoint list -v",
                     substrs=['hit_count = 2'])
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_rw_watchpoint_delete(self):
@@ -162,9 +156,6 @@ class WatchpointCommandsTestCase(TestBas
         self.expect("process status",
                     substrs=['exited'])
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_rw_watchpoint_set_ignore_count(self):
@@ -222,9 +213,6 @@ class WatchpointCommandsTestCase(TestBas
         self.expect("watchpoint list -v",
                     substrs=['hit_count = 2', 'ignore_count = 2'])
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_rw_disable_after_first_stop(self):
@@ -292,9 +280,6 @@ class WatchpointCommandsTestCase(TestBas
         self.expect("watchpoint list -v",
                     substrs=['hit_count = 1'])
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_rw_disable_then_enable(self):

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandLLDB.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandLLDB.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandLLDB.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandLLDB.py Thu Sep  5 22:37:03 2019
@@ -36,9 +36,6 @@ class WatchpointLLDBCommandTestCase(Test
         archs=["aarch64"],
         triple=no_match(".*-android"),
         bugnumber="llvm.org/pr27710") # work on android
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @expectedFailureNetBSD
     def test_watchpoint_command(self):
         """Test 'watchpoint command'."""
@@ -106,9 +103,6 @@ class WatchpointLLDBCommandTestCase(Test
         archs=["aarch64"],
         triple=no_match(".*-android"),
         bugnumber="llvm.org/pr27710") # work on android
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     def test_watchpoint_command_can_disable_a_watchpoint(self):
         """Test that 'watchpoint command' action can disable a watchpoint after it is triggered."""
         self.build(dictionary=self.d)

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/command/TestWatchpointCommandPython.py Thu Sep  5 22:37:03 2019
@@ -34,9 +34,6 @@ class WatchpointPythonCommandTestCase(Te
 
     @skipIfFreeBSD  # timing out on buildbot
     @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
-    @expectedFailureAll(
         oslist=["linux"],
         archs=["aarch64"],
         triple=no_match(".*-android"),
@@ -106,9 +103,6 @@ class WatchpointPythonCommandTestCase(Te
 
     @skipIfFreeBSD  # timing out on buildbot
     @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
-    @expectedFailureAll(
         oslist=["linux"],
         archs=["aarch64"],
         triple=no_match(".*-android"),

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/condition/TestWatchpointConditionCmd.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/condition/TestWatchpointConditionCmd.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/condition/TestWatchpointConditionCmd.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_commands/condition/TestWatchpointConditionCmd.py Thu Sep  5 22:37:03 2019
@@ -36,9 +36,6 @@ class WatchpointConditionCmdTestCase(Tes
         archs=["aarch64"],
         triple=no_match(".*-android"),
         bugnumber="llvm.org/pr27710")
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @expectedFailureNetBSD
     def test_watchpoint_cond(self):
         """Test watchpoint condition."""

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_disable/TestWatchpointDisable.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_disable/TestWatchpointDisable.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_disable/TestWatchpointDisable.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_disable/TestWatchpointDisable.py Thu Sep  5 22:37:03 2019
@@ -15,17 +15,11 @@ class TestWatchpointSetEnable(TestBase):
         # Call super's setUp().
         TestBase.setUp(self)
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     def test_disable_works (self):
         """Set a watchpoint, disable it, and make sure it doesn't get hit."""
         self.build()
         self.do_test(False)
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     def test_disable_enable_works (self):
         """Set a watchpoint, disable it, and make sure it doesn't get hit."""
         self.build()

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_events/TestWatchpointEvents.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_events/TestWatchpointEvents.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_events/TestWatchpointEvents.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_events/TestWatchpointEvents.py Thu Sep  5 22:37:03 2019
@@ -25,9 +25,6 @@ class TestWatchpointEvents (TestBase):
         archs=["aarch64"],
         triple=no_match(".*-android"),
         bugnumber="llvm.org/pr27710")
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     def test_with_python_api(self):
         """Test that adding, deleting and modifying watchpoints sends the appropriate events."""
         self.build()

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_on_vectors/TestValueOfVectorVariable.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_on_vectors/TestValueOfVectorVariable.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_on_vectors/TestValueOfVectorVariable.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_on_vectors/TestValueOfVectorVariable.py Thu Sep  5 22:37:03 2019
@@ -15,9 +15,6 @@ class TestValueOfVectorVariableTestCase(
 
     mydir = TestBase.compute_mydir(__file__)
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     def test_value_of_vector_variable_using_watchpoint_set(self):
         """Test verify displayed value of vector variable."""
         exe = self.getBuildArtifact("a.out")

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_set_command/TestWatchLocationWithWatchSet.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_set_command/TestWatchLocationWithWatchSet.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_set_command/TestWatchLocationWithWatchSet.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_set_command/TestWatchLocationWithWatchSet.py Thu Sep  5 22:37:03 2019
@@ -34,9 +34,6 @@ class WatchLocationUsingWatchpointSetTes
             'aarch64',
             'arm'],
         bugnumber="llvm.org/pr26031")
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @expectedFailureNetBSD
     def test_watchlocation_using_watchpoint_set(self):
         """Test watching a location with 'watchpoint set expression -w write -s size' option."""

Modified: lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_size/TestWatchpointSizes.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_size/TestWatchpointSizes.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_size/TestWatchpointSizes.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/commands/watchpoints/watchpoint_size/TestWatchpointSizes.py Thu Sep  5 22:37:03 2019
@@ -29,27 +29,18 @@ class WatchpointSizeTestCase(TestBase):
         self.exe_name = self.getBuildArtifact("a.out")
         self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name}
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_byte_size_watchpoints_with_byte_selection(self):
         """Test to selectively watch different bytes in a 8-byte array."""
         self.run_watchpoint_size_test('byteArray', 8, '1')
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_two_byte_watchpoints_with_word_selection(self):
         """Test to selectively watch different words in an 8-byte word array."""
         self.run_watchpoint_size_test('wordArray', 4, '2')
 
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_four_byte_watchpoints_with_dword_selection(self):

Modified: lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py Thu Sep  5 22:37:03 2019
@@ -25,9 +25,6 @@ class SetWatchpointAPITestCase(TestBase)
             self.source, '// Set break point at this line.')
 
     @add_test_categories(['pyapi'])
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_watch_val(self):

Modified: lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py Thu Sep  5 22:37:03 2019
@@ -25,9 +25,6 @@ class WatchpointIgnoreCountTestCase(Test
             self.source, '// Set break point at this line.')
 
     @add_test_categories(['pyapi'])
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     # Read-write watchpoints not supported on SystemZ
     @expectedFailureAll(archs=['s390x'])
     def test_set_watch_ignore_count(self):

Modified: lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py Thu Sep  5 22:37:03 2019
@@ -30,9 +30,6 @@ class WatchpointIteratorTestCase(TestBas
             self.source, '// Set break point at this line.')
 
     @add_test_categories(['pyapi'])
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     def test_watch_iter(self):
         """Exercise SBTarget.watchpoint_iter() API to iterate on the available watchpoints."""
         self.build()

Modified: lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py Thu Sep  5 22:37:03 2019
@@ -36,7 +36,6 @@ class WatchpointConditionAPITestCase(Tes
         archs=["aarch64"],
         triple=no_match(".*-android"),
         bugnumber="llvm.org/pr27710")
-    @skipIfWindows  # Watchpoints not supported on Windows, and this test hangs
     def test_watchpoint_cond_api(self):
         """Test watchpoint condition API."""
         self.build(dictionary=self.d)

Modified: lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py Thu Sep  5 22:37:03 2019
@@ -28,9 +28,6 @@ class SetWatchlocationAPITestCase(TestBa
         self.violating_func = "do_bad_thing_with_location"
 
     @add_test_categories(['pyapi'])
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @expectedFailureNetBSD
     def test_watch_location(self):
         """Exercise SBValue.WatchPointee() API to set a watchpoint."""

Modified: lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py Thu Sep  5 22:37:03 2019
@@ -27,9 +27,6 @@ class TargetWatchAddressAPITestCase(Test
         self.violating_func = "do_bad_thing_with_location"
 
     @add_test_categories(['pyapi'])
-    @expectedFailureAll(
-        oslist=["windows"],
-        bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
     @expectedFailureNetBSD
     def test_watch_address(self):
         """Exercise SBTarget.WatchAddress() API to set a watchpoint."""

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/ProcessDebugger.h?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessDebugger.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessDebugger.h Thu Sep  5 22:37:03 2019
@@ -41,7 +41,7 @@ public:
   HANDLE m_initial_stop_event = nullptr;
   bool m_initial_stop_received = false;
   bool m_stop_at_entry;
-  std::map<lldb::tid_t, HostThread> m_new_threads;
+  std::map<lldb::tid_t, lldb::ThreadSP> m_new_threads;
   std::set<lldb::tid_t> m_exited_threads;
 };
 

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp Thu Sep  5 22:37:03 2019
@@ -12,6 +12,7 @@
 #include "lldb/Host/windows/windows.h"
 #include <psapi.h>
 
+#include "lldb/Breakpoint/Watchpoint.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
@@ -104,7 +105,10 @@ const char *ProcessWindows::GetPluginDes
 
 ProcessWindows::ProcessWindows(lldb::TargetSP target_sp,
                                lldb::ListenerSP listener_sp)
-    : lldb_private::Process(target_sp, listener_sp) {}
+    : lldb_private::Process(target_sp, listener_sp),
+      m_watchpoint_ids(
+          RegisterContextWindows::GetNumHardwareBreakpointSlots(),
+          LLDB_INVALID_BREAK_ID) {}
 
 ProcessWindows::~ProcessWindows() {}
 
@@ -382,11 +386,35 @@ void ProcessWindows::RefreshStateAfterSt
       stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread,
                                                                  site->GetID());
       stop_thread->SetStopInfo(stop_info);
-    } else {
-      LLDB_LOG(log, "single stepping thread {0}", stop_thread->GetID());
-      stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
+
+      return;
+    }
+
+    auto *reg_ctx = static_cast<RegisterContextWindows *>(
+        stop_thread->GetRegisterContext().get());
+    uint32_t slot_id = reg_ctx->GetTriggeredHardwareBreakpointSlotId();
+    if (slot_id != LLDB_INVALID_INDEX32) {
+      int id = m_watchpoint_ids[slot_id];
+      LLDB_LOG(log,
+               "Single-stepped onto a watchpoint in process {0} at address "
+               "{1:x} with watchpoint {2}",
+               m_session_data->m_debugger->GetProcess().GetProcessId(), pc, id);
+
+      if (lldb::WatchpointSP wp_sp =
+              GetTarget().GetWatchpointList().FindByID(id))
+        wp_sp->SetHardwareIndex(slot_id);
+
+      stop_info = StopInfo::CreateStopReasonWithWatchpointID(
+          *stop_thread, id, m_watchpoints[id].address);
       stop_thread->SetStopInfo(stop_info);
+
+      return;
     }
+
+    LLDB_LOG(log, "single stepping thread {0}", stop_thread->GetID());
+    stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
+    stop_thread->SetStopInfo(stop_info);
+
     return;
   }
 
@@ -494,9 +522,7 @@ bool ProcessWindows::UpdateThreadList(Th
   // Also add all the threads that are new since the last time we broke into
   // the debugger.
   for (const auto &thread_info : m_session_data->m_new_threads) {
-    ThreadSP thread(new TargetThreadWindows(*this, thread_info.second));
-    thread->SetID(thread_info.first);
-    new_thread_list.AddThread(thread);
+    new_thread_list.AddThread(thread_info.second);
     ++new_size;
     ++new_threads;
     LLDB_LOGV(log, "Thread {0} is new since last update.", thread_info.first);
@@ -588,9 +614,9 @@ void ProcessWindows::OnExitProcess(uint3
   SetProcessExitStatus(GetID(), true, 0, exit_code);
   SetPrivateState(eStateExited);
 
-  // If the process exits before any initial stop then notify the debugger 
+  // If the process exits before any initial stop then notify the debugger
   // of the error otherwise WaitForDebuggerConnection() will be blocked.
-  // An example of this issue is when a process fails to load a dependent DLL. 
+  // An example of this issue is when a process fails to load a dependent DLL.
   if (m_session_data && !m_session_data->m_initial_stop_received) {
     Status error(exit_code, eErrorTypeWin32);
     OnDebuggerError(error, 0);
@@ -619,8 +645,8 @@ void ProcessWindows::OnDebuggerConnected
     FileSystem::Instance().Resolve(executable_file);
     ModuleSpec module_spec(executable_file);
     Status error;
-    module = GetTarget().GetOrCreateModule(module_spec, 
-                                           true /* notify */, &error);
+    module =
+        GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error);
     if (!module) {
       return;
     }
@@ -636,10 +662,15 @@ void ProcessWindows::OnDebuggerConnected
   // returned from DoLaunch() / DoAttach() yet so the target may not have set
   // the process instance to `this` yet.
   llvm::sys::ScopedLock lock(m_mutex);
-  const HostThreadWindows &wmain_thread =
-      debugger->GetMainThread().GetNativeThread();
-  m_session_data->m_new_threads[wmain_thread.GetThreadId()] =
-      debugger->GetMainThread();
+
+  const HostThread &host_main_thread = debugger->GetMainThread();
+  ThreadSP main_thread =
+      std::make_shared<TargetThreadWindows>(*this, host_main_thread);
+
+  tid_t id = host_main_thread.GetNativeThread().GetThreadId();
+  main_thread->SetID(id);
+
+  m_session_data->m_new_threads[id] = main_thread;
 }
 
 ExceptionResult
@@ -711,8 +742,22 @@ ProcessWindows::OnDebugException(bool fi
 
 void ProcessWindows::OnCreateThread(const HostThread &new_thread) {
   llvm::sys::ScopedLock lock(m_mutex);
-  const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
-  m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
+
+  ThreadSP thread = std::make_shared<TargetThreadWindows>(*this, new_thread);
+
+  const HostNativeThread &native_new_thread = new_thread.GetNativeThread();
+  tid_t id = native_new_thread.GetThreadId();
+  thread->SetID(id);
+
+  m_session_data->m_new_threads[id] = thread;
+
+  for (const std::map<int, WatchpointInfo>::value_type &p : m_watchpoints) {
+    auto *reg_ctx = static_cast<RegisterContextWindows *>(
+        thread->GetRegisterContext().get());
+    reg_ctx->AddHardwareBreakpoint(p.second.slot_id, p.second.address,
+                                   p.second.size, p.second.read,
+                                   p.second.write);
+  }
 }
 
 void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
@@ -770,4 +815,106 @@ void ProcessWindows::OnDebuggerError(con
     return;
   }
 }
+
+Status ProcessWindows::GetWatchpointSupportInfo(uint32_t &num) {
+  num = RegisterContextWindows::GetNumHardwareBreakpointSlots();
+  return {};
+}
+
+Status ProcessWindows::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
+  num = RegisterContextWindows::GetNumHardwareBreakpointSlots();
+  after = RegisterContextWindows::DoHardwareBreakpointsTriggerAfter();
+  return {};
+}
+
+Status ProcessWindows::EnableWatchpoint(Watchpoint *wp, bool notify) {
+  Status error;
+
+  if (wp->IsEnabled()) {
+    wp->SetEnabled(true, notify);
+    return error;
+  }
+
+  WatchpointInfo info;
+  for (info.slot_id = 0;
+       info.slot_id < RegisterContextWindows::GetNumHardwareBreakpointSlots();
+       info.slot_id++)
+    if (m_watchpoint_ids[info.slot_id] == LLDB_INVALID_BREAK_ID)
+      break;
+  if (info.slot_id == RegisterContextWindows::GetNumHardwareBreakpointSlots()) {
+    error.SetErrorStringWithFormat("Can't find free slot for watchpoint %i",
+                                   wp->GetID());
+    return error;
+  }
+  info.address = wp->GetLoadAddress();
+  info.size = wp->GetByteSize();
+  info.read = wp->WatchpointRead();
+  info.write = wp->WatchpointWrite();
+
+  for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
+    Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
+    auto *reg_ctx = static_cast<RegisterContextWindows *>(
+        thread->GetRegisterContext().get());
+    if (!reg_ctx->AddHardwareBreakpoint(info.slot_id, info.address, info.size,
+                                        info.read, info.write)) {
+      error.SetErrorStringWithFormat(
+          "Can't enable watchpoint %i on thread 0x%llx", wp->GetID(),
+          thread->GetID());
+      break;
+    }
+  }
+  if (error.Fail()) {
+    for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
+      Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
+      auto *reg_ctx = static_cast<RegisterContextWindows *>(
+          thread->GetRegisterContext().get());
+      reg_ctx->RemoveHardwareBreakpoint(info.slot_id);
+    }
+    return error;
+  }
+
+  m_watchpoints[wp->GetID()] = info;
+  m_watchpoint_ids[info.slot_id] = wp->GetID();
+
+  wp->SetEnabled(true, notify);
+
+  return error;
+}
+
+Status ProcessWindows::DisableWatchpoint(Watchpoint *wp, bool notify) {
+  Status error;
+
+  if (!wp->IsEnabled()) {
+    wp->SetEnabled(false, notify);
+    return error;
+  }
+
+  auto it = m_watchpoints.find(wp->GetID());
+  if (it == m_watchpoints.end()) {
+    error.SetErrorStringWithFormat("Info about watchpoint %i is not found",
+                                   wp->GetID());
+    return error;
+  }
+
+  for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
+    Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
+    auto *reg_ctx = static_cast<RegisterContextWindows *>(
+        thread->GetRegisterContext().get());
+    if (!reg_ctx->RemoveHardwareBreakpoint(it->second.slot_id)) {
+      error.SetErrorStringWithFormat(
+          "Can't disable watchpoint %i on thread 0x%llx", wp->GetID(),
+          thread->GetID());
+      break;
+    }
+  }
+  if (error.Fail())
+    return error;
+
+  m_watchpoint_ids[it->second.slot_id] = LLDB_INVALID_BREAK_ID;
+  m_watchpoints.erase(it);
+
+  wp->SetEnabled(false, notify);
+
+  return error;
+}
 } // namespace lldb_private

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h Thu Sep  5 22:37:03 2019
@@ -98,6 +98,22 @@ public:
   void OnUnloadDll(lldb::addr_t module_addr) override;
   void OnDebugString(const std::string &string) override;
   void OnDebuggerError(const Status &error, uint32_t type) override;
+
+  Status GetWatchpointSupportInfo(uint32_t &num) override;
+  Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
+  Status EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
+  Status DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
+
+private:
+  struct WatchpointInfo {
+    uint32_t slot_id;
+    lldb::addr_t address;
+    uint32_t size;
+    bool read;
+    bool write;
+  };
+  std::map<lldb::break_id_t, WatchpointInfo> m_watchpoints;
+  std::vector<lldb::break_id_t> m_watchpoint_ids;
 };
 } // namespace lldb_private
 

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp Thu Sep  5 22:37:03 2019
@@ -17,6 +17,7 @@
 #include "TargetThreadWindows.h"
 
 #include "llvm/ADT/STLExtras.h"
+#include "lldb/Target/Target.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -52,13 +53,7 @@ bool RegisterContextWindows::WriteAllReg
   assert(data_sp->GetByteSize() >= sizeof(m_context));
   memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context));
 
-  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
-  if (!::SetThreadContext(
-          wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
-          &m_context))
-    return false;
-
-  return true;
+  return ApplyAllRegisterValues();
 }
 
 uint32_t RegisterContextWindows::ConvertRegisterKindToRegisterNumber(
@@ -76,37 +71,69 @@ uint32_t RegisterContextWindows::Convert
   return LLDB_INVALID_REGNUM;
 }
 
-// Subclasses can these functions if desired
-uint32_t RegisterContextWindows::NumSupportedHardwareBreakpoints() {
-  // Support for hardware breakpoints not yet implemented.
-  return 0;
-}
+bool RegisterContextWindows::HardwareSingleStep(bool enable) { return false; }
 
-uint32_t RegisterContextWindows::SetHardwareBreakpoint(lldb::addr_t addr,
-                                                       size_t size) {
-  return 0;
-}
+bool RegisterContextWindows::AddHardwareBreakpoint(uint32_t slot,
+                                                   lldb::addr_t address,
+                                                   uint32_t size, bool read,
+                                                   bool write) {
+  if (slot >= NUM_HARDWARE_BREAKPOINT_SLOTS)
+    return false;
+
+  switch (size) {
+  case 1:
+  case 2:
+  case 4:
+#if defined(_M_AMD64)
+  case 8:
+#endif
+    break;
+  default:
+    return false;
+  }
 
-bool RegisterContextWindows::ClearHardwareBreakpoint(uint32_t hw_idx) {
-  return false;
-}
+  if (!CacheAllRegisterValues())
+    return false;
 
-uint32_t RegisterContextWindows::NumSupportedHardwareWatchpoints() {
-  // Support for hardware watchpoints not yet implemented.
-  return 0;
-}
+  unsigned shift = 2 * slot;
+  m_context.Dr7 |= 1ULL << shift;
+
+  (&m_context.Dr0)[slot] = address;
+
+  shift = 18 + 4 * slot;
+  m_context.Dr7 &= ~(3ULL << shift);
+  m_context.Dr7 |= (size == 8 ? 2ULL : size - 1) << shift;
 
-uint32_t RegisterContextWindows::SetHardwareWatchpoint(lldb::addr_t addr,
-                                                       size_t size, bool read,
-                                                       bool write) {
-  return 0;
+  shift = 16 + 4 * slot;
+  m_context.Dr7 &= ~(3ULL << shift);
+  m_context.Dr7 |= (read ? 3ULL : (write ? 1ULL : 0)) << shift;
+
+  return ApplyAllRegisterValues();
 }
 
-bool RegisterContextWindows::ClearHardwareWatchpoint(uint32_t hw_index) {
-  return false;
+bool RegisterContextWindows::RemoveHardwareBreakpoint(uint32_t slot) {
+  if (slot >= NUM_HARDWARE_BREAKPOINT_SLOTS)
+    return false;
+
+  if (!CacheAllRegisterValues())
+    return false;
+
+  unsigned shift = 2 * slot;
+  m_context.Dr7 &= ~(1ULL << shift);
+
+  return ApplyAllRegisterValues();
 }
 
-bool RegisterContextWindows::HardwareSingleStep(bool enable) { return false; }
+uint32_t RegisterContextWindows::GetTriggeredHardwareBreakpointSlotId() {
+  if (!CacheAllRegisterValues())
+    return LLDB_INVALID_INDEX32;
+
+  for (unsigned i = 0UL; i < NUM_HARDWARE_BREAKPOINT_SLOTS; i++)
+    if (m_context.Dr6 & (1ULL << i))
+      return i;
+
+  return LLDB_INVALID_INDEX32;
+}
 
 bool RegisterContextWindows::CacheAllRegisterValues() {
   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
@@ -146,3 +173,9 @@ bool RegisterContextWindows::CacheAllReg
   m_context_stale = false;
   return true;
 }
+
+bool RegisterContextWindows::ApplyAllRegisterValues() {
+  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+  return ::SetThreadContext(
+      wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
+}

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.h?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/RegisterContextWindows.h Thu Sep  5 22:37:03 2019
@@ -33,28 +33,28 @@ public:
   uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
                                                uint32_t num) override;
 
-  // Subclasses can override these functions if desired
-  uint32_t NumSupportedHardwareBreakpoints() override;
-
-  uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
-  bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
-  uint32_t NumSupportedHardwareWatchpoints() override;
-
-  uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
-                                 bool write) override;
+  bool HardwareSingleStep(bool enable) override;
 
-  bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+  static constexpr uint32_t GetNumHardwareBreakpointSlots() {
+    return NUM_HARDWARE_BREAKPOINT_SLOTS;
+  }
+  static constexpr bool DoHardwareBreakpointsTriggerAfter() { return true; }
+
+  bool AddHardwareBreakpoint(uint32_t slot, lldb::addr_t address, uint32_t size,
+                             bool read, bool write);
+  bool RemoveHardwareBreakpoint(uint32_t slot);
 
-  bool HardwareSingleStep(bool enable) override;
+  uint32_t GetTriggeredHardwareBreakpointSlotId();
 
 protected:
+  static constexpr unsigned NUM_HARDWARE_BREAKPOINT_SLOTS = 4;
+
   virtual bool CacheAllRegisterValues();
+  virtual bool ApplyAllRegisterValues();
 
   CONTEXT m_context;
   bool m_context_stale;
 };
-}
+} // namespace lldb_private
 
 #endif // #ifndef liblldb_RegisterContextWindows_H_

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp Thu Sep  5 22:37:03 2019
@@ -532,9 +532,7 @@ bool RegisterContextWindows_x64::WriteRe
   }
 
   // Physically update the registers in the target process.
-  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
-  return ::SetThreadContext(
-      wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
+  return ApplyAllRegisterValues();
 }
 
 #endif // defined(__x86_64__) || defined(_M_X64)

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp?rev=371166&r1=371165&r2=371166&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp Thu Sep  5 22:37:03 2019
@@ -267,9 +267,7 @@ bool RegisterContextWindows_x86::WriteRe
   }
 
   // Physically update the registers in the target process.
-  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
-  return ::SetThreadContext(
-      wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
+  return ApplyAllRegisterValues();
 }
 
 bool RegisterContextWindows_x86::ReadRegisterHelper(




More information about the lldb-commits mailing list