diff options
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test')
5 files changed, 232 insertions, 14 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/Makefile new file mode 100644 index 00000000000..3665ae323e7 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../../make + +ENABLE_THREADS := YES +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py new file mode 100644 index 00000000000..21fe084d3df --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py @@ -0,0 +1,114 @@ +""" +Test hardware breakpoints for multiple threads. +""" + +from __future__ import print_function + + +import os +import time +import re +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +# Hardware breakpoints are supported only by platforms mentioned in oslist. +@skipUnlessPlatform(oslist=['linux']) +class HardwareBreakpointMultiThreadTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + mydir = TestBase.compute_mydir(__file__) + + # LLDB supports hardware breakpoints for arm and aarch64 architectures. + @skipIf(archs=no_match(['arm', 'aarch64'])) + @expectedFailureAndroid + def test_hw_break_set_delete_multi_thread(self): + self.build() + self.setTearDownCleanup() + self.break_multi_thread('delete') + + # LLDB supports hardware breakpoints for arm and aarch64 architectures. + @skipIf(archs=no_match(['arm', 'aarch64'])) + @expectedFailureAndroid + def test_hw_break_set_disable_multi_thread(self): + self.build() + self.setTearDownCleanup() + self.break_multi_thread('disable') + + 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.first_stop = line_number( + self.source, 'Starting thread creation with hardware breakpoint set') + + def break_multi_thread(self, removal_type): + """Test that lldb hardware breakpoints work for multiple threads.""" + self.runCmd( + "file %s" % + os.path.join( + os.getcwd(), + 'a.out'), + CURRENT_EXECUTABLE_SET) + + # Stop in main before creating any threads. + lldbutil.run_break_set_by_file_and_line( + self, None, self.first_stop, num_expected_locations=1) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # We should be stopped again due to the breakpoint. + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Now set a hardware breakpoint in thread function. + self.expect("breakpoint set -b hw_break_function --hardware", + substrs=[ + 'Breakpoint', + 'hw_break_function', + 'address = 0x']) + + # We should stop in hw_break_function function for 4 threads. + count = 0 + + while count < 2 : + + self.runCmd("process continue") + + # We should be stopped in hw_break_function + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=[ + 'stop reason = breakpoint', + 'hw_break_function']) + + # Continue the loop and test that we are stopped 4 times. + count += 1 + + if removal_type == 'delete': + self.runCmd("settings set auto-confirm true") + + # Now 'breakpoint delete' should just work fine without confirmation + # prompt from the command interpreter. + self.expect("breakpoint delete", + startstr="All breakpoints removed") + + # Restore the original setting of auto-confirm. + self.runCmd("settings clear auto-confirm") + + elif removal_type == 'disable': + self.expect("breakpoint disable", + startstr="All breakpoints disabled.") + + # Continue. Program should exit without stopping anywhere. + self.runCmd("process continue") + + # Process should have stopped and exited with status = 0 + self.expect("process status", PROCESS_STOPPED, + patterns=['Process .* exited with status = 0']) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/main.cpp new file mode 100644 index 00000000000..d13393095c6 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/main.cpp @@ -0,0 +1,51 @@ +//===-- 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 <cstdio> +#include <mutex> +#include <random> +#include <thread> + +#define NUM_OF_THREADS 4 + +std::mutex hw_break_mutex; + +void +hw_break_function (uint32_t thread_index) { + printf ("%s called by Thread #%u...\n", __FUNCTION__, thread_index); +} + + +void +thread_func (uint32_t thread_index) { + printf ("%s (thread index = %u) starting...\n", __FUNCTION__, thread_index); + + hw_break_mutex.lock(); + + hw_break_function(thread_index); // Call hw_break_function + + hw_break_mutex.unlock(); +} + + +int main (int argc, char const *argv[]) +{ + std::thread threads[NUM_OF_THREADS]; + + printf ("Starting thread creation with hardware breakpoint set...\n"); + + for (auto &thread : threads) + thread = std::thread{thread_func, std::distance(threads, &thread)}; + + for (auto &thread : threads) + thread.join(); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py index b69ac3f8d2a..6f36fbea470 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py @@ -1082,7 +1082,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcod self.set_inferior_startup_launch() self.qMemoryRegionInfo_reports_heap_address_as_readable_writeable() - def software_breakpoint_set_and_remove_work(self): + def breakpoint_set_and_remove_work(self, want_hardware=False): # Start up the inferior. procs = self.prep_debug_monitor_and_inferior( inferior_args=[ @@ -1126,15 +1126,27 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcod self.assertIsNotNone(context.get("function_address")) function_address = int(context.get("function_address"), 16) + # Get current target architecture + target_arch = self.getArchitecture() + # Set the breakpoint. - if self.getArchitecture() == "arm": + if (target_arch == "arm") or (target_arch == "aarch64"): # TODO: Handle case when setting breakpoint in thumb code BREAKPOINT_KIND = 4 else: BREAKPOINT_KIND = 1 + + # Set default packet type to Z0 (software breakpoint) + z_packet_type = 0 + + # If hardware breakpoint is requested set packet type to Z1 + if want_hardware == True: + z_packet_type = 1 + self.reset_test_sequence() self.add_set_breakpoint_packets( function_address, + z_packet_type, do_continue=True, breakpoint_kind=BREAKPOINT_KIND) @@ -1182,13 +1194,15 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcod # Verify that a breakpoint remove and continue gets us the expected # output. self.reset_test_sequence() + + # Add breakpoint remove packets + self.add_remove_breakpoint_packets( + function_address, + z_packet_type, + breakpoint_kind=BREAKPOINT_KIND) + self.test_sequence.add_log_lines( [ - # Remove the breakpoint. - "read packet: $z0,{0:x},{1}#00".format( - function_address, BREAKPOINT_KIND), - # Verify the stub could unset it. - "send packet: $OK#00", # Continue running. "read packet: $c#63", # We should now receive the output from the call. @@ -1209,7 +1223,7 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcod else: self.build() self.set_inferior_startup_launch() - self.software_breakpoint_set_and_remove_work() + self.breakpoint_set_and_remove_work(want_hardware=False) @llgs_test @expectedFlakeyLinux("llvm.org/pr25652") @@ -1221,7 +1235,35 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcod else: self.build() self.set_inferior_startup_launch() - self.software_breakpoint_set_and_remove_work() + self.breakpoint_set_and_remove_work(want_hardware=False) + + @debugserver_test + @skipUnlessPlatform(oslist=['linux']) + @expectedFailureAndroid + @skipIf(archs=no_match(['arm', 'aarch64'])) + def test_hardware_breakpoint_set_and_remove_work_debugserver(self): + self.init_debugserver_test() + if self.getArchitecture() == "arm": + # TODO: Handle case when setting breakpoint in thumb code + self.build(dictionary={'CFLAGS_EXTRAS': '-marm'}) + else: + self.build() + self.set_inferior_startup_launch() + self.breakpoint_set_and_remove_work(want_hardware=True) + + @llgs_test + @skipUnlessPlatform(oslist=['linux']) + @expectedFailureAndroid + @skipIf(archs=no_match(['arm', 'aarch64'])) + def test_hardware_breakpoint_set_and_remove_work_llgs(self): + self.init_llgs_test() + if self.getArchitecture() == "arm": + # TODO: Handle case when setting breakpoint in thumb code + self.build(dictionary={'CFLAGS_EXTRAS': '-marm'}) + else: + self.build() + self.set_inferior_startup_launch() + self.breakpoint_set_and_remove_work(want_hardware=True) def qSupported_returns_known_stub_features(self): # Start up the stub and start/prep the inferior. diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py index f6e09f6164d..23cb8693585 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -883,12 +883,13 @@ class GdbRemoteTestCaseBase(TestBase): def add_set_breakpoint_packets( self, address, + z_packet_type=0, do_continue=True, breakpoint_kind=1): self.test_sequence.add_log_lines( [ # Set the breakpoint. - "read packet: $Z0,{0:x},{1}#00".format( - address, breakpoint_kind), + "read packet: $Z{2},{0:x},{1}#00".format( + address, breakpoint_kind, z_packet_type), # Verify the stub could set it. "send packet: $OK#00", ], True) @@ -904,11 +905,15 @@ class GdbRemoteTestCaseBase(TestBase): 2: "stop_thread_id"}}, ], True) - def add_remove_breakpoint_packets(self, address, breakpoint_kind=1): + def add_remove_breakpoint_packets( + self, + address, + z_packet_type=0, + breakpoint_kind=1): self.test_sequence.add_log_lines( [ # Remove the breakpoint. - "read packet: $z0,{0:x},{1}#00".format( - address, breakpoint_kind), + "read packet: $z{2},{0:x},{1}#00".format( + address, breakpoint_kind, z_packet_type), # Verify the stub could unset it. "send packet: $OK#00", ], True) |