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/watchlocation | |
| parent | 3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff) | |
Notes
Diffstat (limited to 'packages/Python/lldbsuite/test/python_api/watchpoint/watchlocation')
4 files changed, 330 insertions, 0 deletions
| 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; +} | 
