From 61b440f5005f0bf4e5864ba9cff4107ac56be404 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 29 May 2017 16:26:31 +0000 Subject: Vendor import of lldb trunk r304149: https://llvm.org/svn/llvm-project/lldb/trunk@304149 --- .../unwind_expression/TestUnwindExpression.py | 65 +++++-- .../expression_command/unwind_expression/main.cpp | 8 + .../lldbsuite/test/functionalities/thread/Makefile | 5 - .../test/functionalities/thread/TestNumThreads.py | 61 ------ .../lldbsuite/test/functionalities/thread/main.cpp | 50 ----- .../functionalities/thread/num_threads/Makefile | 5 + .../thread/num_threads/TestNumThreads.py | 61 ++++++ .../functionalities/thread/num_threads/main.cpp | 50 +++++ .../sbstructureddata/TestStructuredDataAPI.py | 206 +++++++++++++++++++++ 9 files changed, 377 insertions(+), 134 deletions(-) delete mode 100644 packages/Python/lldbsuite/test/functionalities/thread/Makefile delete mode 100644 packages/Python/lldbsuite/test/functionalities/thread/TestNumThreads.py delete mode 100644 packages/Python/lldbsuite/test/functionalities/thread/main.cpp create mode 100644 packages/Python/lldbsuite/test/functionalities/thread/num_threads/Makefile create mode 100644 packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py create mode 100644 packages/Python/lldbsuite/test/functionalities/thread/num_threads/main.cpp create mode 100644 packages/Python/lldbsuite/test/python_api/sbstructureddata/TestStructuredDataAPI.py (limited to 'packages/Python') diff --git a/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py b/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py index bfd6f4642c6cb..9cc585b75aa1a 100644 --- a/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py +++ b/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py @@ -18,15 +18,9 @@ from lldbsuite.test import lldbutil class UnwindFromExpressionTest(TestBase): mydir = TestBase.compute_mydir(__file__) + main_spec = lldb.SBFileSpec("main.cpp", False) - def setUp(self): - # Call super's setUp(). - TestBase.setUp(self) - - @add_test_categories(['pyapi']) - @expectedFailureAll(oslist=["windows"]) - def test_unwind_expression(self): - """Test unwinding from an expression.""" + def build_and_run_to_bkpt(self): self.build() exe = os.path.join(os.getcwd(), "a.out") @@ -35,9 +29,8 @@ class UnwindFromExpressionTest(TestBase): self.assertTrue(target, VALID_TARGET) # Create the breakpoint. - main_spec = lldb.SBFileSpec("main.cpp", False) breakpoint = target.BreakpointCreateBySourceRegex( - "// Set a breakpoint here to get started", main_spec) + "// Set a breakpoint here to get started", self.main_spec) self.assertTrue(breakpoint, VALID_BREAKPOINT) # Launch the process, and do not stop at the entry point. @@ -52,24 +45,60 @@ class UnwindFromExpressionTest(TestBase): "instead the actual state is: '%s'" % lldbutil.state_type_to_str(process.GetState())) - thread = lldbutil.get_one_thread_stopped_at_breakpoint( + self.thread = lldbutil.get_one_thread_stopped_at_breakpoint( process, breakpoint) self.assertIsNotNone( - thread, "Expected one thread to be stopped at the breakpoint") + self.thread, "Expected one thread to be stopped at the breakpoint") + + # Next set a breakpoint in this function, set up Expression options to stop on + # breakpoint hits, and call the function. + self.fun_bkpt = self.target().BreakpointCreateBySourceRegex( + "// Stop inside the function here.", self.main_spec) + self.assertTrue(self.fun_bkpt, VALID_BREAKPOINT) + + + @no_debug_info_test + @expectedFailureAll(bugnumber="llvm.org/pr33164") + def test_conditional_bktp(self): + """ + Test conditional breakpoint handling in the IgnoreBreakpoints = False case + """ + self.build_and_run_to_bkpt() + + self.fun_bkpt.SetCondition("0") # Should not get hit + options = lldb.SBExpressionOptions() + options.SetIgnoreBreakpoints(False) + options.SetUnwindOnError(False) + + main_frame = self.thread.GetFrameAtIndex(0) + val = main_frame.EvaluateExpression("second_function(47)", options) + self.assertTrue( + val.GetError().Success(), + "We did complete the execution.") + self.assertEquals(47, val.GetValueAsSigned()) + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"]) + def test_unwind_expression(self): + """Test unwinding from an expression.""" + self.build_and_run_to_bkpt() + + # Run test with varying one thread timeouts to also test the halting + # logic in the IgnoreBreakpoints = False case + self.do_unwind_test(self.thread, self.fun_bkpt, 1000) + self.do_unwind_test(self.thread, self.fun_bkpt, 100000) + + def do_unwind_test(self, thread, bkpt, timeout): # # Use Python API to evaluate expressions while stopped in a stack frame. # main_frame = thread.GetFrameAtIndex(0) - # Next set a breakpoint in this function, set up Expression options to stop on - # breakpoint hits, and call the function. - fun_bkpt = target.BreakpointCreateBySourceRegex( - "// Stop inside the function here.", main_spec) - self.assertTrue(fun_bkpt, VALID_BREAKPOINT) options = lldb.SBExpressionOptions() options.SetIgnoreBreakpoints(False) options.SetUnwindOnError(False) + options.SetOneThreadTimeoutInMicroSeconds(timeout) val = main_frame.EvaluateExpression("a_function_to_call()", options) @@ -82,7 +111,7 @@ class UnwindFromExpressionTest(TestBase): "And the reason was right.") thread = lldbutil.get_one_thread_stopped_at_breakpoint( - process, fun_bkpt) + self.process(), bkpt) self.assertTrue( thread.IsValid(), "We are indeed stopped at our breakpoint") diff --git a/packages/Python/lldbsuite/test/expression_command/unwind_expression/main.cpp b/packages/Python/lldbsuite/test/expression_command/unwind_expression/main.cpp index e93c34a30b036..56b06f31eccae 100644 --- a/packages/Python/lldbsuite/test/expression_command/unwind_expression/main.cpp +++ b/packages/Python/lldbsuite/test/expression_command/unwind_expression/main.cpp @@ -7,8 +7,16 @@ a_function_to_call() return static_value; } +int second_function(int x){ + for(int i=0; i<10; ++i) { + a_function_to_call(); + } + return x; +} + int main (int argc, char const *argv[]) { a_function_to_call(); // Set a breakpoint here to get started + second_function(1); return 0; } diff --git a/packages/Python/lldbsuite/test/functionalities/thread/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/Makefile deleted file mode 100644 index 644e2971a2c12..0000000000000 --- a/packages/Python/lldbsuite/test/functionalities/thread/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -LEVEL = ../../make - -CXX_SOURCES := main.cpp -ENABLE_THREADS := YES -include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/thread/TestNumThreads.py b/packages/Python/lldbsuite/test/functionalities/thread/TestNumThreads.py deleted file mode 100644 index 094c867059699..0000000000000 --- a/packages/Python/lldbsuite/test/functionalities/thread/TestNumThreads.py +++ /dev/null @@ -1,61 +0,0 @@ -""" -Test number of threads. -""" - -from __future__ import print_function - - -import os -import time -import lldb -from lldbsuite.test.lldbtest import * -import lldbsuite.test.lldbutil as lldbutil - - -class NumberOfThreadsTestCase(TestBase): - - mydir = TestBase.compute_mydir(__file__) - - def setUp(self): - # Call super's setUp(). - TestBase.setUp(self) - # Find the line number to break inside main(). - self.line = line_number('main.cpp', '// Set break point at this line.') - - def test(self): - """Test number of threads.""" - self.build() - exe = os.path.join(os.getcwd(), "a.out") - self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) - - # This should create a breakpoint with 1 location. - lldbutil.run_break_set_by_file_and_line( - self, "main.cpp", self.line, num_expected_locations=1) - - # The breakpoint list should show 3 locations. - self.expect( - "breakpoint list -f", - "Breakpoint location shown correctly", - substrs=[ - "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % - self.line]) - - # Run the program. - self.runCmd("run", RUN_SUCCEEDED) - - # Stopped once. - self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, - substrs=["stop reason = breakpoint 1."]) - - # Get the target process - target = self.dbg.GetSelectedTarget() - process = target.GetProcess() - - # Get the number of threads - num_threads = process.GetNumThreads() - - # Using std::thread may involve extra threads, so we assert that there are - # at least 4 rather than exactly 4. - self.assertTrue( - num_threads >= 4, - 'Number of expected threads and actual threads do not match.') diff --git a/packages/Python/lldbsuite/test/functionalities/thread/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/main.cpp deleted file mode 100644 index 6a0ea4e0d1191..0000000000000 --- a/packages/Python/lldbsuite/test/functionalities/thread/main.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include - -std::mutex mutex; -std::condition_variable cond; - -void * -thread3(void *input) -{ - std::unique_lock lock(mutex); - cond.notify_all(); // Set break point at this line. - return NULL; -} - -void * -thread2(void *input) -{ - std::unique_lock lock(mutex); - cond.notify_all(); - cond.wait(lock); - return NULL; -} - -void * -thread1(void *input) -{ - std::thread thread_2(thread2, nullptr); - thread_2.join(); - - return NULL; -} - -int main() -{ - std::unique_lock lock(mutex); - - std::thread thread_1(thread1, nullptr); - cond.wait(lock); - - std::thread thread_3(thread3, nullptr); - cond.wait(lock); - - lock.unlock(); - - thread_1.join(); - thread_3.join(); - - return 0; -} diff --git a/packages/Python/lldbsuite/test/functionalities/thread/num_threads/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/Makefile new file mode 100644 index 0000000000000..67aa16625bff4 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py new file mode 100644 index 0000000000000..094c867059699 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py @@ -0,0 +1,61 @@ +""" +Test number of threads. +""" + +from __future__ import print_function + + +import os +import time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class NumberOfThreadsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.cpp', '// Set break point at this line.') + + def test(self): + """Test number of threads.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # This should create a breakpoint with 1 location. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1) + + # The breakpoint list should show 3 locations. + self.expect( + "breakpoint list -f", + "Breakpoint location shown correctly", + substrs=[ + "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % + self.line]) + + # Run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # Stopped once. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=["stop reason = breakpoint 1."]) + + # Get the target process + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + # Get the number of threads + num_threads = process.GetNumThreads() + + # Using std::thread may involve extra threads, so we assert that there are + # at least 4 rather than exactly 4. + self.assertTrue( + num_threads >= 4, + 'Number of expected threads and actual threads do not match.') diff --git a/packages/Python/lldbsuite/test/functionalities/thread/num_threads/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/main.cpp new file mode 100644 index 0000000000000..6a0ea4e0d1191 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/main.cpp @@ -0,0 +1,50 @@ +#include +#include +#include + +std::mutex mutex; +std::condition_variable cond; + +void * +thread3(void *input) +{ + std::unique_lock lock(mutex); + cond.notify_all(); // Set break point at this line. + return NULL; +} + +void * +thread2(void *input) +{ + std::unique_lock lock(mutex); + cond.notify_all(); + cond.wait(lock); + return NULL; +} + +void * +thread1(void *input) +{ + std::thread thread_2(thread2, nullptr); + thread_2.join(); + + return NULL; +} + +int main() +{ + std::unique_lock lock(mutex); + + std::thread thread_1(thread1, nullptr); + cond.wait(lock); + + std::thread thread_3(thread3, nullptr); + cond.wait(lock); + + lock.unlock(); + + thread_1.join(); + thread_3.join(); + + return 0; +} diff --git a/packages/Python/lldbsuite/test/python_api/sbstructureddata/TestStructuredDataAPI.py b/packages/Python/lldbsuite/test/python_api/sbstructureddata/TestStructuredDataAPI.py new file mode 100644 index 0000000000000..f19d01d5e695e --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/sbstructureddata/TestStructuredDataAPI.py @@ -0,0 +1,206 @@ +""" +Test some SBStructuredData API. +""" + +from __future__ import print_function + +import os +import re +import time + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestStructuredDataAPI(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test(self): + self.structured_data_api_test() + + def setUp(self): + TestBase.setUp(self) + + @add_test_categories(['pyapi']) + def structured_data_api_test(self): + error = lldb.SBError() + s = lldb.SBStream() + s.Print( + "{\"key_dict\":{\"key_string\":\"STRING\",\"key_int\":3,\"key_float\":2.99,\"key_bool\":true,\"key_array\":[\"23\",\"arr\"]}}") + example = lldb.SBStructuredData() + + # Check SetFromJSON API for dictionaries, integers, floating point + # values, strings and arrays + error = example.SetFromJSON(s) + if not error.Success(): + self.fail("FAILED: " + error.GetCString()) + + # Tests for invalid data type + self.invalid_struct_test(example) + + dict_struct = lldb.SBStructuredData() + dict_struct = example.GetValueForKey("key_dict") + + # Tests for dictionary data type + self.dictionary_struct_test(example) + + # Tests for string data type + self.string_struct_test(dict_struct) + + # Tests for integer data type + self.int_struct_test(dict_struct) + + # Tests for floating point data type + self.double_struct_test(dict_struct) + + # Tests for boolean data type + self.bool_struct_test(dict_struct) + + # Tests for array data type + self.array_struct_test(dict_struct) + + def invalid_struct_test(self, example): + invalid_struct = lldb.SBStructuredData() + invalid_struct = example.GetValueForKey("invalid_key") + if invalid_struct.IsValid(): + self.fail("An invalid object should have been returned") + + # Check Type API + if not invalid_struct.GetType() == lldb.eStructuredDataTypeInvalid: + self.fail("Wrong type returned: " + str(invalid_struct.GetType())) + + def dictionary_struct_test(self, example): + # Check API returning a valid SBStructuredData of 'dictionary' type + dict_struct = lldb.SBStructuredData() + dict_struct = example.GetValueForKey("key_dict") + if not dict_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not dict_struct.GetType() == lldb.eStructuredDataTypeDictionary: + self.fail("Wrong type returned: " + str(dict_struct.GetType())) + + # Check Size API for 'dictionary' type + if not dict_struct.GetSize() == 5: + self.fail("Wrong no of elements returned: " + + str(dict_struct.GetSize())) + + def string_struct_test(self, dict_struct): + string_struct = lldb.SBStructuredData() + string_struct = dict_struct.GetValueForKey("key_string") + if not string_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not string_struct.GetType() == lldb.eStructuredDataTypeString: + self.fail("Wrong type returned: " + str(string_struct.GetType())) + + # Check API returning 'string' value + output = string_struct.GetStringValue(25) + if not "STRING" in output: + self.fail("wrong output: " + output) + + # Calling wrong API on a SBStructuredData + # (e.g. getting an integer from a string type structure) + output = string_struct.GetIntegerValue() + if output: + self.fail( + "Valid integer value " + + str(output) + + " returned for a string object") + + def int_struct_test(self, dict_struct): + # Check a valid SBStructuredData containing an 'integer' by + int_struct = lldb.SBStructuredData() + int_struct = dict_struct.GetValueForKey("key_int") + if not int_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not int_struct.GetType() == lldb.eStructuredDataTypeInteger: + self.fail("Wrong type returned: " + str(int_struct.GetType())) + + # Check API returning 'integer' value + output = int_struct.GetIntegerValue() + if not output == 3: + self.fail("wrong output: " + str(output)) + + # Calling wrong API on a SBStructuredData + # (e.g. getting a string value from an integer type structure) + output = int_struct.GetStringValue(25) + if output: + self.fail( + "Valid string " + + output + + " returned for an integer object") + + def double_struct_test(self, dict_struct): + floating_point_struct = lldb.SBStructuredData() + floating_point_struct = dict_struct.GetValueForKey("key_float") + if not floating_point_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not floating_point_struct.GetType() == lldb.eStructuredDataTypeFloat: + self.fail("Wrong type returned: " + + str(floating_point_struct.GetType())) + + # Check API returning 'double' value + output = floating_point_struct.GetFloatValue() + if not output == 2.99: + self.fail("wrong output: " + str(output)) + + def bool_struct_test(self, dict_struct): + bool_struct = lldb.SBStructuredData() + bool_struct = dict_struct.GetValueForKey("key_bool") + if not bool_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not bool_struct.GetType() == lldb.eStructuredDataTypeBoolean: + self.fail("Wrong type returned: " + str(bool_struct.GetType())) + + # Check API returning 'bool' value + output = bool_struct.GetBooleanValue() + if not output: + self.fail("wrong output: " + str(output)) + + def array_struct_test(self, dict_struct): + # Check API returning a valid SBStructuredData of 'array' type + array_struct = lldb.SBStructuredData() + array_struct = dict_struct.GetValueForKey("key_array") + if not array_struct.IsValid(): + self.fail("A valid object should have been returned") + + # Check Type API + if not array_struct.GetType() == lldb.eStructuredDataTypeArray: + self.fail("Wrong type returned: " + str(array_struct.GetType())) + + # Check Size API for 'array' type + if not array_struct.GetSize() == 2: + self.fail("Wrong no of elements returned: " + + str(array_struct.GetSize())) + + # Check API returning a valid SBStructuredData for different 'array' + # indices + string_struct = array_struct.GetItemAtIndex(0) + if not string_struct.IsValid(): + self.fail("A valid object should have been returned") + if not string_struct.GetType() == lldb.eStructuredDataTypeString: + self.fail("Wrong type returned: " + str(string_struct.GetType())) + output = string_struct.GetStringValue(5) + if not output == "23": + self.fail("wrong output: " + str(output)) + + string_struct = array_struct.GetItemAtIndex(1) + if not string_struct.IsValid(): + self.fail("A valid object should have been returned") + if not string_struct.GetType() == lldb.eStructuredDataTypeString: + self.fail("Wrong type returned: " + str(string_struct.GetType())) + output = string_struct.GetStringValue(5) + if not output == "arr": + self.fail("wrong output: " + str(output)) -- cgit v1.3