diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 | 
| commit | 9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (patch) | |
| tree | dd2a1ddf0476664c2b823409c36cbccd52662ca7 /packages/Python/lldbsuite/test/python_api/watchpoint | |
| parent | 3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff) | |
Notes
Diffstat (limited to 'packages/Python/lldbsuite/test/python_api/watchpoint')
12 files changed, 778 insertions, 0 deletions
| diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile b/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile new file mode 100644 index 000000000000..0d70f2595019 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py b/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py new file mode 100644 index 000000000000..264e21240dd9 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/TestSetWatchpoint.py @@ -0,0 +1,93 @@ +""" +Use lldb Python SBValue API to create a watchpoint for read_write of 'globl' var. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class SetWatchpointAPITestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    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']) +    @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported +    @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows +    def test_watch_val(self): +        """Exercise SBValue.Watch() API to set a watchpoint.""" +        self.build() +        exe = os.path.join(os.getcwd(), "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) diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py b/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py new file mode 100644 index 000000000000..a15e73347030 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIgnoreCount.py @@ -0,0 +1,89 @@ +""" +Use lldb Python SBWatchpoint API to set the ignore count. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class WatchpointIgnoreCountTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    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']) +    @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported +    @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows +    def test_set_watch_ignore_count(self): +        """Test SBWatchpoint.SetIgnoreCount() API.""" +        self.build() +        exe = os.path.join(os.getcwd(), "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, 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.assertTrue(target.GetNumWatchpoints() == 1) +        watchpoint = target.GetWatchpointAtIndex(0) +        self.assertTrue(watchpoint.IsEnabled()) +        self.assertTrue(watchpoint.GetIgnoreCount() == 0) +        watch_id = watchpoint.GetID() +        self.assertTrue(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.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED) + +        # Verify some vital statistics. +        self.assertTrue(watchpoint) +        self.assertTrue(watchpoint.GetWatchSize() == 4) +        self.assertTrue(watchpoint.GetHitCount() == 2) +        print(watchpoint) diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py b/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py new file mode 100644 index 000000000000..315450280675 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/TestWatchpointIter.py @@ -0,0 +1,115 @@ +""" +Use lldb Python SBTarget API to iterate on the watchpoint(s) for the target. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class WatchpointIteratorTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    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']) +    @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported +    @expectedFailureWindows("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() +        exe = os.path.join(os.getcwd(), "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, 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.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) +        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/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile b/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile new file mode 100644 index 000000000000..314f1cb2f077 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/condition/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py b/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py new file mode 100644 index 000000000000..f30bf856aa07 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py @@ -0,0 +1,89 @@ +""" +Test watchpoint condition API. +""" + +from __future__ import print_function + + + +import os, time +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class WatchpointConditionAPITestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    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} + +    @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported +    @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) +        self.setTearDownCleanup(dictionary=self.d) +        exe = os.path.join(os.getcwd(), 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/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp b/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp new file mode 100644 index 000000000000..f4c3527f8af2 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/condition/main.cpp @@ -0,0 +1,28 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#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/packages/Python/lldbsuite/test/python_api/watchpoint/main.c b/packages/Python/lldbsuite/test/python_api/watchpoint/main.c new file mode 100644 index 000000000000..4753edfba991 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/main.c @@ -0,0 +1,24 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#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/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile new file mode 100644 index 000000000000..8817fff55e8c --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py new file mode 100644 index 000000000000..5a4a464657d6 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py @@ -0,0 +1,90 @@ +""" +Use lldb Python SBValue.WatchPointee() API to create a watchpoint for write of '*g_char_ptr'. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class SetWatchlocationAPITestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    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']) +    @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported +    @expectedFailureWindows("llvm.org/pr24446") # WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows +    def test_watch_location(self): +        """Exercise SBValue.WatchPointee() API to set a watchpoint.""" +        self.build() +        exe = os.path.join(os.getcwd(), "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/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py new file mode 100644 index 000000000000..6facbaa8f2e9 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py @@ -0,0 +1,130 @@ +""" +Use lldb Python SBtarget.WatchAddress() API to create a watchpoint for write of '*g_char_ptr'. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class TargetWatchAddressAPITestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    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']) +    @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported +    @expectedFailureWindows("llvm.org/pr24446") +    def test_watch_address(self): +        """Exercise SBTarget.WatchAddress() API to set a watchpoint.""" +        self.build() +        exe = os.path.join(os.getcwd(), "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']) +    @expectedFailureAndroid(archs=['arm', 'aarch64']) # Watchpoints not supported +    @skipIf(archs=['mips', 'mipsel', 'mips64', 'mips64el']) # No size constraint on MIPS for watches +    def test_watch_address_with_invalid_watch_size(self): +        """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size.""" +        self.build() +        exe = os.path.join(os.getcwd(), "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/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp new file mode 100644 index 000000000000..a197a92a4814 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation/main.cpp @@ -0,0 +1,104 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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; +} | 
