diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint')
13 files changed, 827 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/.categories new file mode 100644 index 00000000000..50c1613cda7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/.categories @@ -0,0 +1 @@ +watchpoint diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py new file mode 100644 index 00000000000..a34806d1657 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py @@ -0,0 +1,106 @@ +""" +Use lldb Python SBValue API to create a watchpoint for read_write of 'globl' var. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SetWatchpointAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Our simple source filename. + self.source = 'main.c' + # Find the line number to break inside main(). + self.line = line_number( + self.source, '// Set break point at this line.') + + @add_test_categories(['pyapi']) + # Read-write watchpoints not supported on SystemZ + @expectedFailureAll(archs=['s390x']) + def test_watch_val(self): + """Exercise SBValue.Watch() API to set a watchpoint.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create a breakpoint on main.c. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + # Watch 'global' for read and write. + value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) + error = lldb.SBError() + watchpoint = value.Watch(True, True, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the variable and set a watchpoint") + self.DebugSBValue(value) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print(watchpoint) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + + # Continue. Expect the program to stop due to the variable being read + # from. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + + # Continue the process. We don't expect the program to be stopped + # again. + process.Continue() + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) + + self.dbg.DeleteTarget(target) + self.assertFalse(watchpoint.IsValid()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py new file mode 100644 index 00000000000..83a11d42346 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py @@ -0,0 +1,92 @@ +""" +Use lldb Python SBWatchpoint API to set the ignore count. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class WatchpointIgnoreCountTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Our simple source filename. + self.source = 'main.c' + # Find the line number to break inside main(). + self.line = line_number( + self.source, '// Set break point at this line.') + + @add_test_categories(['pyapi']) + # Read-write watchpoints not supported on SystemZ + @expectedFailureAll(archs=['s390x']) + def test_set_watch_ignore_count(self): + """Test SBWatchpoint.SetIgnoreCount() API.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create a breakpoint on main.c in order to set our watchpoint later. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertEqual(process.GetState(), lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + # Watch 'global' for read and write. + value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) + error = lldb.SBError() + watchpoint = value.Watch(True, True, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the variable and set a watchpoint") + self.DebugSBValue(value) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + # There should be only 1 watchpoint location under the target. + self.assertEqual(target.GetNumWatchpoints(), 1) + watchpoint = target.GetWatchpointAtIndex(0) + self.assertTrue(watchpoint.IsEnabled()) + self.assertEqual(watchpoint.GetIgnoreCount(), 0) + watch_id = watchpoint.GetID() + self.assertNotEqual(watch_id, 0) + print(watchpoint) + + # Now immediately set the ignore count to 2. When we continue, expect the + # inferior to run to its completion without stopping due to watchpoint. + watchpoint.SetIgnoreCount(2) + print(watchpoint) + process.Continue() + + # At this point, the inferior process should have exited. + self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED) + + # Verify some vital statistics. + self.assertTrue(watchpoint) + self.assertEqual(watchpoint.GetWatchSize(), 4) + self.assertEqual(watchpoint.GetHitCount(), 2) + print(watchpoint) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py new file mode 100644 index 00000000000..44df96bae5e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py @@ -0,0 +1,125 @@ +""" +Use lldb Python SBTarget API to iterate on the watchpoint(s) for the target. +""" + +from __future__ import print_function + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class WatchpointIteratorTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + # hardware watchpoints are not reported with a hardware index # on armv7 on ios devices + def affected_by_radar_34564183(self): + return (self.getArchitecture() in ['armv7', 'armv7k', 'arm64_32']) and self.platformIsDarwin() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Our simple source filename. + self.source = 'main.c' + # Find the line number to break inside main(). + self.line = line_number( + self.source, '// Set break point at this line.') + + @add_test_categories(['pyapi']) + def test_watch_iter(self): + """Exercise SBTarget.watchpoint_iter() API to iterate on the available watchpoints.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create a breakpoint on main.c in order to set our watchpoint later. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + # Watch 'global' for read and write. + value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) + error = lldb.SBError() + watchpoint = value.Watch(True, False, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the variable and set a watchpoint") + self.DebugSBValue(value) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + # There should be only 1 watchpoint location under the target. + self.assertTrue(target.GetNumWatchpoints() == 1) + self.assertTrue(watchpoint.IsEnabled()) + watch_id = watchpoint.GetID() + self.assertTrue(watch_id != 0) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + # Print the stack traces. + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + + # We currently only support hardware watchpoint. Verify that we have a + # meaningful hardware index at this point. Exercise the printed repr of + # SBWatchpointLocation. + print(watchpoint) + if not self.affected_by_radar_34564183(): + self.assertTrue(watchpoint.GetHardwareIndex() != -1) + + # SBWatchpoint.GetDescription() takes a description level arg. + print(lldbutil.get_description(watchpoint, lldb.eDescriptionLevelFull)) + + # Now disable the 'rw' watchpoint. The program won't stop when it reads + # 'global' next. + watchpoint.SetEnabled(False) + self.assertTrue(watchpoint.GetHardwareIndex() == -1) + self.assertFalse(watchpoint.IsEnabled()) + + # Continue. The program does not stop again when the variable is being + # read from because the watchpoint location has been disabled. + process.Continue() + + # At this point, the inferior process should have exited. + self.assertTrue( + process.GetState() == lldb.eStateExited, + PROCESS_EXITED) + + # Verify some vital statistics and exercise the iterator API. + for watchpoint in target.watchpoint_iter(): + self.assertTrue(watchpoint) + self.assertTrue(watchpoint.GetWatchSize() == 4) + self.assertTrue(watchpoint.GetHitCount() == 1) + print(watchpoint) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py new file mode 100644 index 00000000000..733473411ac --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py @@ -0,0 +1,95 @@ +""" +Test watchpoint condition API. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class WatchpointConditionAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Our simple source filename. + self.source = 'main.cpp' + # Find the line number to break inside main(). + self.line = line_number( + self.source, '// Set break point at this line.') + # And the watchpoint variable declaration line number. + self.decl = line_number(self.source, + '// Watchpoint variable declaration.') + # 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} + + def test_watchpoint_cond_api(self): + """Test watchpoint condition API.""" + self.build(dictionary=self.d) + self.setTearDownCleanup(dictionary=self.d) + exe = self.getBuildArtifact(self.exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create a breakpoint on main.c. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + # Watch 'global' for write. + value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) + error = lldb.SBError() + watchpoint = value.Watch(True, False, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the variable and set a watchpoint") + self.DebugSBValue(value) + + # Now set the condition as "global==5". + watchpoint.SetCondition('global==5') + self.expect(watchpoint.GetCondition(), exe=False, + startstr='global==5') + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print(watchpoint) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + + # Verify that the condition is met. + self.assertTrue(value.GetValueAsUnsigned() == 5) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp new file mode 100644 index 00000000000..3f7c5f5be96 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp @@ -0,0 +1,27 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <stdint.h> + +int32_t global = 0; // Watchpoint variable declaration. + +static void modify(int32_t &var) { + ++var; +} + +int main(int argc, char** argv) { + int local = 0; + printf("&global=%p\n", &global); + printf("about to write to 'global'...\n"); // Set break point at this line. + // When stopped, watch 'global', + // for the condition "global == 5". + for (int i = 0; i < 10; ++i) + modify(global); + + printf("global=%d\n", global); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/main.c new file mode 100644 index 00000000000..6cda6d7c886 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/main.c @@ -0,0 +1,23 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <stdint.h> + +int32_t global = 10; // Watchpoint variable declaration. + +int main(int argc, char** argv) { + int local = 0; + printf("&global=%p\n", &global); + printf("about to write to 'global'...\n"); // Set break point at this line. + // When stopped, watch 'global' for read&write. + global = 20; + local += argc; + ++local; + printf("local: %d\n", local); + printf("global=%d\n", global); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile new file mode 100644 index 00000000000..de4ec12b13c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile @@ -0,0 +1,4 @@ +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py new file mode 100644 index 00000000000..9cbc396e7a5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py @@ -0,0 +1,100 @@ +""" +Use lldb Python SBValue.WatchPointee() API to create a watchpoint for write of '*g_char_ptr'. +""" + +from __future__ import print_function + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SetWatchlocationAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Our simple source filename. + self.source = 'main.cpp' + # Find the line number to break inside main(). + self.line = line_number( + self.source, '// Set break point at this line.') + # This is for verifying that watch location works. + self.violating_func = "do_bad_thing_with_location" + + @add_test_categories(['pyapi']) + def test_watch_location(self): + """Exercise SBValue.WatchPointee() API to set a watchpoint.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create a breakpoint on main.c. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + value = frame0.FindValue('g_char_ptr', + lldb.eValueTypeVariableGlobal) + pointee = value.CreateValueFromAddress( + "pointee", + value.GetValueAsUnsigned(0), + value.GetType().GetPointeeType()) + # Watch for write to *g_char_ptr. + error = lldb.SBError() + watchpoint = value.WatchPointee(True, False, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the pointer and set a watchpoint") + self.DebugSBValue(value) + self.DebugSBValue(pointee) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print(watchpoint) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + self.DebugSBValue(pointee) + + self.expect( + lldbutil.print_stacktrace( + thread, + string_buffer=True), + exe=False, + substrs=[ + self.violating_func]) + + # This finishes our test. diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py new file mode 100644 index 00000000000..53e794db03f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py @@ -0,0 +1,145 @@ +""" +Use lldb Python SBtarget.WatchAddress() API to create a watchpoint for write of '*g_char_ptr'. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TargetWatchAddressAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Our simple source filename. + self.source = 'main.cpp' + # Find the line number to break inside main(). + self.line = line_number( + self.source, '// Set break point at this line.') + # This is for verifying that watch location works. + self.violating_func = "do_bad_thing_with_location" + + @add_test_categories(['pyapi']) + def test_watch_address(self): + """Exercise SBTarget.WatchAddress() API to set a watchpoint.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create a breakpoint on main.c. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + value = frame0.FindValue('g_char_ptr', + lldb.eValueTypeVariableGlobal) + pointee = value.CreateValueFromAddress( + "pointee", + value.GetValueAsUnsigned(0), + value.GetType().GetPointeeType()) + # Watch for write to *g_char_ptr. + error = lldb.SBError() + watchpoint = target.WatchAddress( + value.GetValueAsUnsigned(), 1, False, True, error) + self.assertTrue(value and watchpoint, + "Successfully found the pointer and set a watchpoint") + self.DebugSBValue(value) + self.DebugSBValue(pointee) + + # Hide stdout if not running with '-t' option. + if not self.TraceOn(): + self.HideStdout() + + print(watchpoint) + + # Continue. Expect the program to stop due to the variable being + # written to. + process.Continue() + + if (self.TraceOn()): + lldbutil.print_stacktraces(process) + + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonWatchpoint) + self.assertTrue(thread, "The thread stopped due to watchpoint") + self.DebugSBValue(value) + self.DebugSBValue(pointee) + + self.expect( + lldbutil.print_stacktrace( + thread, + string_buffer=True), + exe=False, + substrs=[ + self.violating_func]) + + # This finishes our test. + + @add_test_categories(['pyapi']) + # No size constraint on MIPS for watches + @skipIf(archs=['mips', 'mipsel', 'mips64', 'mips64el']) + @skipIf(archs=['s390x']) # Likewise on SystemZ + def test_watch_address_with_invalid_watch_size(self): + """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create a breakpoint on main.c. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # We should be stopped due to the breakpoint. Get frame #0. + process = target.GetProcess() + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + frame0 = thread.GetFrameAtIndex(0) + + value = frame0.FindValue('g_char_ptr', + lldb.eValueTypeVariableGlobal) + pointee = value.CreateValueFromAddress( + "pointee", + value.GetValueAsUnsigned(0), + value.GetType().GetPointeeType()) + # Watch for write to *g_char_ptr. + error = lldb.SBError() + watchpoint = target.WatchAddress( + value.GetValueAsUnsigned(), 365, False, True, error) + self.assertFalse(watchpoint) + self.expect(error.GetCString(), exe=False, + substrs=['watch size of %d is not supported' % 365]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp new file mode 100644 index 00000000000..e455331bc16 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp @@ -0,0 +1,103 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <chrono> +#include <condition_variable> +#include <cstdio> +#include <random> +#include <thread> + +std::default_random_engine g_random_engine{std::random_device{}()}; +std::uniform_int_distribution<> g_distribution{0, 3000000}; +std::condition_variable g_condition_variable; +std::mutex g_mutex; +int g_count; + +char *g_char_ptr = nullptr; + +void +barrier_wait() +{ + std::unique_lock<std::mutex> lock{g_mutex}; + if (--g_count > 0) + g_condition_variable.wait(lock); + else + g_condition_variable.notify_all(); +} + +void +do_bad_thing_with_location(char *char_ptr, char new_val) +{ + *char_ptr = new_val; +} + +uint32_t +access_pool (bool flag = false) +{ + static std::mutex g_access_mutex; + if (!flag) + g_access_mutex.lock(); + + char old_val = *g_char_ptr; + if (flag) + do_bad_thing_with_location(g_char_ptr, old_val + 1); + + if (!flag) + g_access_mutex.unlock(); + return *g_char_ptr; +} + +void +thread_func (uint32_t thread_index) +{ + printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index); + + barrier_wait(); + + uint32_t count = 0; + uint32_t val; + while (count++ < 15) + { + // random micro second sleep from zero to 3 seconds + int usec = g_distribution(g_random_engine); + printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec); + std::this_thread::sleep_for(std::chrono::microseconds{usec}); + + if (count < 7) + val = access_pool (); + else + val = access_pool (true); + + printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count); + } + printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index); +} + + +int main (int argc, char const *argv[]) +{ + g_count = 4; + std::thread threads[3]; + + g_char_ptr = new char{}; + + // Create 3 threads + for (auto &thread : threads) + thread = std::thread{thread_func, std::distance(threads, &thread)}; + + printf ("Before turning all three threads loose...\n"); // Set break point at this line. + barrier_wait(); + + // Join all of our threads + for (auto &thread : threads) + thread.join(); + + delete g_char_ptr; + + return 0; +} |