From 78b9749c0a4ea980a8b934645da6ae98fcc665e8 Mon Sep 17 00:00:00 2001 From: dim Date: Wed, 6 Jan 2016 20:12:03 +0000 Subject: Vendor import of lldb trunk r256945: https://llvm.org/svn/llvm-project/lldb/trunk@256945 --- .../lldbsuite/test/expression_command/.categories | 1 + .../test/expression_command/call-function/Makefile | 15 ++ .../call-function/TestCallStdStringFunction.py | 43 ++++ .../call-function/TestCallStopAndContinue.py | 46 ++++ .../call-function/TestCallUserDefinedFunction.py | 52 +++++ .../test/expression_command/call-function/main.cpp | 53 +++++ .../test/expression_command/call-restarts/Makefile | 5 + .../call-restarts/TestCallThatRestarts.py | 139 ++++++++++++ .../call-restarts/lotta-signals.c | 61 +++++ .../test/expression_command/call-throws/Makefile | 6 + .../call-throws/TestCallThatThrows.py | 112 ++++++++++ .../expression_command/call-throws/call-throws.m | 47 ++++ .../test/expression_command/char/Makefile | 5 + .../test/expression_command/char/TestExprsChar.py | 69 ++++++ .../test/expression_command/char/main.cpp | 10 + .../expression_command/expr-in-syscall/Makefile | 5 + .../expr-in-syscall/TestExpressionInSyscall.py | 82 +++++++ .../expression_command/expr-in-syscall/main.cpp | 12 + .../test/expression_command/formatters/Makefile | 5 + .../formatters/TestFormatters.py | 167 ++++++++++++++ .../test/expression_command/formatters/foosynth.py | 29 +++ .../expression_command/formatters/formatters.py | 17 ++ .../test/expression_command/formatters/main.cpp | 48 ++++ .../test/expression_command/issue_11588/Makefile | 5 + .../expression_command/issue_11588/Test11588.py | 77 +++++++ .../test/expression_command/issue_11588/main.cpp | 54 +++++ .../test/expression_command/issue_11588/s11588.py | 26 +++ .../test/expression_command/macros/Makefile | 8 + .../test/expression_command/macros/TestMacros.py | 106 +++++++++ .../test/expression_command/macros/macro1.h | 17 ++ .../test/expression_command/macros/macro2.h | 8 + .../test/expression_command/macros/main.cpp | 15 ++ .../test/expression_command/options/Makefile | 5 + .../expression_command/options/TestExprOptions.py | 76 +++++++ .../test/expression_command/options/foo.cpp | 11 + .../test/expression_command/options/main.cpp | 15 ++ .../persist_objc_pointeetype/Makefile | 7 + .../TestPersistObjCPointeeType.py | 50 +++++ .../persist_objc_pointeetype/main.m | 80 +++++++ .../persistent_ptr_update/Makefile | 7 + .../TestPersistentPtrUpdate.py | 41 ++++ .../persistent_ptr_update/main.c | 11 + .../expression_command/persistent_types/Makefile | 5 + .../persistent_types/TestNestedPersistentTypes.py | 41 ++++ .../persistent_types/TestPersistentTypes.py | 57 +++++ .../expression_command/persistent_types/main.c | 14 ++ .../persistent_variables/Makefile | 5 + .../TestPersistentVariables.py | 54 +++++ .../expression_command/persistent_variables/main.c | 14 ++ .../test/expression_command/po_verbosity/Makefile | 6 + .../po_verbosity/TestPoVerbosity.py | 61 +++++ .../test/expression_command/po_verbosity/main.m | 9 + .../test/expression_command/radar_8638051/Makefile | 5 + .../radar_8638051/Test8638051.py | 39 ++++ .../test/expression_command/radar_8638051/main.c | 54 +++++ .../test/expression_command/radar_9531204/Makefile | 5 + .../radar_9531204/TestPrintfAfterUp.py | 42 ++++ .../test/expression_command/radar_9531204/main.c | 25 +++ .../test/expression_command/radar_9673664/Makefile | 5 + .../radar_9673664/TestExprHelpExamples.py | 41 ++++ .../test/expression_command/radar_9673664/main.c | 16 ++ .../test/expression_command/test/Makefile | 5 + .../test/expression_command/test/TestExprs.py | 248 +++++++++++++++++++++ .../test/expression_command/test/TestExprs2.py | 60 +++++ .../test/expression_command/test/main.cpp | 44 ++++ .../test/expression_command/timeout/Makefile | 5 + .../timeout/TestCallWithTimeout.py | 92 ++++++++ .../expression_command/timeout/wait-a-while.cpp | 35 +++ .../test/expression_command/two-files/Makefile | 7 + .../TestObjCTypeQueryFromOtherCompileUnit.py | 39 ++++ .../test/expression_command/two-files/foo.m | 28 +++ .../test/expression_command/two-files/main.m | 22 ++ 72 files changed, 2731 insertions(+) create mode 100644 packages/Python/lldbsuite/test/expression_command/.categories create mode 100644 packages/Python/lldbsuite/test/expression_command/call-function/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py create mode 100644 packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py create mode 100644 packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py create mode 100644 packages/Python/lldbsuite/test/expression_command/call-function/main.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/call-restarts/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py create mode 100644 packages/Python/lldbsuite/test/expression_command/call-restarts/lotta-signals.c create mode 100644 packages/Python/lldbsuite/test/expression_command/call-throws/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py create mode 100644 packages/Python/lldbsuite/test/expression_command/call-throws/call-throws.m create mode 100644 packages/Python/lldbsuite/test/expression_command/char/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py create mode 100644 packages/Python/lldbsuite/test/expression_command/char/main.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/expr-in-syscall/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py create mode 100644 packages/Python/lldbsuite/test/expression_command/expr-in-syscall/main.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/formatters/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py create mode 100644 packages/Python/lldbsuite/test/expression_command/formatters/foosynth.py create mode 100644 packages/Python/lldbsuite/test/expression_command/formatters/formatters.py create mode 100644 packages/Python/lldbsuite/test/expression_command/formatters/main.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/issue_11588/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py create mode 100644 packages/Python/lldbsuite/test/expression_command/issue_11588/main.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/issue_11588/s11588.py create mode 100644 packages/Python/lldbsuite/test/expression_command/macros/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py create mode 100644 packages/Python/lldbsuite/test/expression_command/macros/macro1.h create mode 100644 packages/Python/lldbsuite/test/expression_command/macros/macro2.h create mode 100644 packages/Python/lldbsuite/test/expression_command/macros/main.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/options/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/options/TestExprOptions.py create mode 100644 packages/Python/lldbsuite/test/expression_command/options/foo.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/options/main.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py create mode 100644 packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/main.m create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/main.c create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_types/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_types/main.c create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_variables/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_variables/TestPersistentVariables.py create mode 100644 packages/Python/lldbsuite/test/expression_command/persistent_variables/main.c create mode 100644 packages/Python/lldbsuite/test/expression_command/po_verbosity/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py create mode 100644 packages/Python/lldbsuite/test/expression_command/po_verbosity/main.m create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_8638051/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_8638051/Test8638051.py create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_8638051/main.c create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_9531204/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_9531204/main.c create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_9673664/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py create mode 100644 packages/Python/lldbsuite/test/expression_command/radar_9673664/main.c create mode 100644 packages/Python/lldbsuite/test/expression_command/test/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/test/TestExprs.py create mode 100644 packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py create mode 100644 packages/Python/lldbsuite/test/expression_command/test/main.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/timeout/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py create mode 100644 packages/Python/lldbsuite/test/expression_command/timeout/wait-a-while.cpp create mode 100644 packages/Python/lldbsuite/test/expression_command/two-files/Makefile create mode 100644 packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py create mode 100644 packages/Python/lldbsuite/test/expression_command/two-files/foo.m create mode 100644 packages/Python/lldbsuite/test/expression_command/two-files/main.m (limited to 'packages/Python/lldbsuite/test/expression_command') diff --git a/packages/Python/lldbsuite/test/expression_command/.categories b/packages/Python/lldbsuite/test/expression_command/.categories new file mode 100644 index 0000000..897e40a --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/.categories @@ -0,0 +1 @@ +expression diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/Makefile b/packages/Python/lldbsuite/test/expression_command/call-function/Makefile new file mode 100644 index 0000000..d4b82b3 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-function/Makefile @@ -0,0 +1,15 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD +# targets. Other targets do not, which causes this test to fail. +# This flag enables FullDebugInfo for all targets. +ifneq (,$(findstring clang,$(CC))) + CFLAGS_EXTRAS += -fno-limit-debug-info +endif + +include $(LEVEL)/Makefile.rules + +clean:: + rm -rf $(wildcard *.o *.d *.dSYM) diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py new file mode 100644 index 0000000..3756b4a --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py @@ -0,0 +1,43 @@ +""" +Test calling std::String member functions. +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprCommandCallFunctionTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.c. + self.line = line_number('main.cpp', + '// Please test these expressions while stopped at this line:') + + @expectedFailureIcc # llvm.org/pr14437, fails with ICC 13.1 + @expectedFailureFreeBSD('llvm.org/pr17807') # Fails on FreeBSD buildbot + @expectedFailureWindows("llvm.org/pr21765") + def test_with(self): + """Test calling std::String member function.""" + self.build() + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + # Some versions of GCC encode two locations for the 'return' statement in main.cpp + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + self.expect("print str", + substrs = ['Hello world']) + + # Calling this function now succeeds, but we follow the typedef return type through to + # const char *, and thus don't invoke the Summary formatter. + self.expect("print str.c_str()", + substrs = ['Hello world']) diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py new file mode 100644 index 0000000..f6d6388 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py @@ -0,0 +1,46 @@ +""" +Test calling a function, stopping in the call, continue and gather the result on stop. +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprCommandCallStopContinueTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.c. + self.line = line_number('main.cpp', + '// Please test these expressions while stopped at this line:') + self.func_line = line_number ('main.cpp', + '{ 5, "five" }') + + @expectedFlakeyDarwin("llvm.org/pr20274") + @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows") + def test(self): + """Test gathering result from interrupted function call.""" + self.build() + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + # Some versions of GCC encode two locations for the 'return' statement in main.cpp + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.func_line, num_expected_locations=-1, loc_exact=True) + + self.expect("expr -i false -- returnsFive()", error=True, + substrs = ['Execution was interrupted, reason: breakpoint']) + + self.runCmd("continue", "Continue completed") + self.expect ("thread list", + substrs = ['stop reason = User Expression thread plan', + r'Completed expression: (Five) $0 = (number = 5, name = "five")']) diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py new file mode 100644 index 0000000..9138af0 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py @@ -0,0 +1,52 @@ +""" +Test calling user defined functions using expression evaluation. + +Note: + LLDBs current first choice of evaluating functions is using the IR interpreter, + which is only supported on Hexagon. Otherwise JIT is used for the evaluation. + +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprCommandCallUserDefinedFunction(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.c. + self.line = line_number('main.cpp', + '// Please test these expressions while stopped at this line:') + @expectedFlakeyDsym("llvm.org/pr20274") + @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows") + def test(self): + """Test return values of user defined function calls.""" + self.build() + + # Set breakpoint in main and run exe + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # Test recursive function call. + self.expect("expr fib(5)", substrs = ['$0 = 5']) + + # Test function with more than one paramter + self.expect("expr add(4,8)", substrs = ['$1 = 12']) + + # Test nesting function calls in function paramters + self.expect("expr add(add(5,2),add(3,4))", substrs = ['$2 = 14']) + self.expect("expr add(add(5,2),fib(5))", substrs = ['$3 = 12']) + + # Test function with pointer paramter + self.expect("exp stringCompare((const char*) \"Hello world\")", substrs = ['$4 = true']) + self.expect("exp stringCompare((const char*) \"Hellworld\")", substrs = ['$5 = false']) diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/main.cpp b/packages/Python/lldbsuite/test/expression_command/call-function/main.cpp new file mode 100644 index 0000000..9b494c7 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-function/main.cpp @@ -0,0 +1,53 @@ +#include +#include +#include + +struct Five +{ + int number; + const char *name; +}; + +Five +returnsFive() +{ + Five my_five = { 5, "five" }; + return my_five; +} + +unsigned int +fib(unsigned int n) +{ + if (n < 2) + return n; + else + return fib(n - 1) + fib(n - 2); +} + +int +add(int a, int b) +{ + return a + b; +} + +bool +stringCompare(const char *str) +{ + if (strcmp( str, "Hello world" ) == 0) + return true; + else + return false; +} + +int main (int argc, char const *argv[]) +{ + std::string str = "Hello world"; + std::cout << str << std::endl; + std::cout << str.c_str() << std::endl; + Five main_five = returnsFive(); +#if 0 + print str + print str.c_str() +#endif + return 0; // Please test these expressions while stopped at this line: +} diff --git a/packages/Python/lldbsuite/test/expression_command/call-restarts/Makefile b/packages/Python/lldbsuite/test/expression_command/call-restarts/Makefile new file mode 100644 index 0000000..1c93ae1 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-restarts/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := lotta-signals.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py b/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py new file mode 100644 index 0000000..abf4874 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py @@ -0,0 +1,139 @@ +""" +Test calling a function that hits a signal set to auto-restart, make sure the call completes. +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprCommandThatRestartsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + self.main_source = "lotta-signals.c" + self.main_source_spec = lldb.SBFileSpec (self.main_source) + + @skipIfFreeBSD # llvm.org/pr19246: intermittent failure + @skipIfDarwin # llvm.org/pr19246: intermittent failure + @skipIfWindows # Test relies on signals, unsupported on Windows + def test(self): + """Test calling function that hits a signal and restarts.""" + self.build() + self.call_function() + + def check_after_call (self, num_sigchld): + after_call = self.sigchld_no.GetValueAsSigned(-1) + self.assertTrue (after_call - self.start_sigchld_no == num_sigchld, "Really got %d SIGCHLD signals through the call."%(num_sigchld)) + self.start_sigchld_no = after_call + + # Check that we are back where we were before: + frame = self.thread.GetFrameAtIndex(0) + self.assertTrue (self.orig_frame_pc == frame.GetPC(), "Restored the zeroth frame correctly") + + def call_function(self): + exe_name = "a.out" + exe = os.path.join(os.getcwd(), exe_name) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + empty = lldb.SBFileSpec() + breakpoint = target.BreakpointCreateBySourceRegex('Stop here in main.',self.main_source_spec) + self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # Frame #0 should be at our breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint) + + self.assertTrue(len(threads) == 1) + self.thread = threads[0] + + # Make sure the SIGCHLD behavior is pass/no-stop/no-notify: + return_obj = lldb.SBCommandReturnObject() + self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 0", return_obj) + self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop") + + # The sigchld_no variable should be 0 at this point. + self.sigchld_no = target.FindFirstGlobalVariable("sigchld_no") + self.assertTrue (self.sigchld_no.IsValid(), "Got a value for sigchld_no") + + self.start_sigchld_no = self.sigchld_no.GetValueAsSigned (-1) + self.assertTrue (self.start_sigchld_no != -1, "Got an actual value for sigchld_no") + + options = lldb.SBExpressionOptions() + # processing 30 signals takes a while, increase the expression timeout a bit + options.SetTimeoutInMicroSeconds(3000000) # 3s + options.SetUnwindOnError(True) + + frame = self.thread.GetFrameAtIndex(0) + # Store away the PC to check that the functions unwind to the right place after calls + self.orig_frame_pc = frame.GetPC() + + num_sigchld = 30 + value = frame.EvaluateExpression ("call_me (%d)"%(num_sigchld), options) + self.assertTrue (value.IsValid()) + self.assertTrue (value.GetError().Success() == True) + self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld) + + self.check_after_call(num_sigchld) + + # Okay, now try with a breakpoint in the called code in the case where + # we are ignoring breakpoint hits. + handler_bkpt = target.BreakpointCreateBySourceRegex("Got sigchld %d.", self.main_source_spec) + self.assertTrue (handler_bkpt.GetNumLocations() > 0) + options.SetIgnoreBreakpoints(True) + options.SetUnwindOnError(True) + + value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options) + + self.assertTrue (value.IsValid() and value.GetError().Success() == True) + self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld) + self.check_after_call(num_sigchld) + + # Now set the signal to print but not stop and make sure that calling still works: + self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 1", return_obj) + self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop, notify") + + value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options) + + self.assertTrue (value.IsValid() and value.GetError().Success() == True) + self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld) + self.check_after_call(num_sigchld) + + # Now set this unwind on error to false, and make sure that we still complete the call: + options.SetUnwindOnError(False) + value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options) + + self.assertTrue (value.IsValid() and value.GetError().Success() == True) + self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld) + self.check_after_call(num_sigchld) + + # Okay, now set UnwindOnError to true, and then make the signal behavior to stop + # and see that now we do stop at the signal point: + + self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 1 -p 1 -n 1", return_obj) + self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, stop, notify") + + value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options) + self.assertTrue (value.IsValid() and value.GetError().Success() == False) + + # Set signal handling back to no-stop, and continue and we should end up back in out starting frame: + self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 1", return_obj) + self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop, notify") + + error = process.Continue() + self.assertTrue (error.Success(), "Continuing after stopping for signal succeeds.") + + frame = self.thread.GetFrameAtIndex(0) + self.assertTrue (frame.GetPC() == self.orig_frame_pc, "Continuing returned to the place we started.") diff --git a/packages/Python/lldbsuite/test/expression_command/call-restarts/lotta-signals.c b/packages/Python/lldbsuite/test/expression_command/call-restarts/lotta-signals.c new file mode 100644 index 0000000..f5c15b4 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-restarts/lotta-signals.c @@ -0,0 +1,61 @@ +#include +#include +#include + +static int sigchld_no; +static int nosig_no; +static int weird_value; + +void +sigchld_handler (int signo) +{ + sigchld_no++; + printf ("Got sigchld %d.\n", sigchld_no); +} + +int +call_me (int some_value) +{ + int ret_val = 0; + int i; + for (i = 0; i < some_value; i++) + { + int result = 0; + if (i%2 == 0) + result = kill (getpid(), SIGCHLD); + else + sigchld_no++; + + usleep(1000); + if (result == 0) + ret_val++; + } + usleep (10000); + return ret_val; +} + +int +call_me_nosig (int some_value) +{ + int ret_val = 0; + int i; + for (i = 0; i < some_value; i++) + weird_value += i % 4; + + nosig_no += some_value; + return some_value; +} + +int +main () +{ + int ret_val; + signal (SIGCHLD, sigchld_handler); + + ret_val = call_me (2); // Stop here in main. + + ret_val = call_me_nosig (10); + + return 0; + +} diff --git a/packages/Python/lldbsuite/test/expression_command/call-throws/Makefile b/packages/Python/lldbsuite/test/expression_command/call-throws/Makefile new file mode 100644 index 0000000..ac07b31 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-throws/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../make + +OBJC_SOURCES := call-throws.m + +include $(LEVEL)/Makefile.rules +LDFLAGS += -framework Foundation diff --git a/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py b/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py new file mode 100644 index 0000000..0e766ac --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py @@ -0,0 +1,112 @@ +""" +Test calling a function that throws an ObjC exception, make sure that it doesn't propagate the exception. +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprCommandWithThrowTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + self.main_source = "call-throws.m" + self.main_source_spec = lldb.SBFileSpec (self.main_source) + + @skipUnlessDarwin + def test(self): + """Test calling a function that throws and ObjC exception.""" + self.build() + self.call_function() + + def check_after_call (self): + # Check that we are back where we were before: + frame = self.thread.GetFrameAtIndex(0) + self.assertTrue (self.orig_frame_pc == frame.GetPC(), "Restored the zeroth frame correctly") + + + def call_function(self): + """Test calling function that throws.""" + exe_name = "a.out" + exe = os.path.join(os.getcwd(), exe_name) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateBySourceRegex('I am about to throw.',self.main_source_spec) + self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # Frame #0 should be at our breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint) + + self.assertTrue(len(threads) == 1) + self.thread = threads[0] + + options = lldb.SBExpressionOptions() + options.SetUnwindOnError(True) + + frame = self.thread.GetFrameAtIndex(0) + # Store away the PC to check that the functions unwind to the right place after calls + self.orig_frame_pc = frame.GetPC() + + value = frame.EvaluateExpression ("[my_class callMeIThrow]", options) + self.assertTrue (value.IsValid()) + self.assertTrue (value.GetError().Success() == False) + + self.check_after_call() + + # Okay, now try with a breakpoint in the called code in the case where + # we are ignoring breakpoint hits. + handler_bkpt = target.BreakpointCreateBySourceRegex("I felt like it", self.main_source_spec) + self.assertTrue (handler_bkpt.GetNumLocations() > 0) + options.SetIgnoreBreakpoints(True) + options.SetUnwindOnError(True) + + value = frame.EvaluateExpression ("[my_class callMeIThrow]", options) + + self.assertTrue (value.IsValid() and value.GetError().Success() == False) + self.check_after_call() + + # Now set the ObjC language breakpoint and make sure that doesn't interfere with the call: + exception_bkpt = target.BreakpointCreateForException (lldb.eLanguageTypeObjC, False, True) + self.assertTrue(exception_bkpt.GetNumLocations() > 0) + + options.SetIgnoreBreakpoints(True) + options.SetUnwindOnError(True) + + value = frame.EvaluateExpression ("[my_class callMeIThrow]", options) + + self.assertTrue (value.IsValid() and value.GetError().Success() == False) + self.check_after_call() + + + # Now turn off exception trapping, and call a function that catches the exceptions, + # and make sure the function actually completes, and we get the right value: + options.SetTrapExceptions(False) + value = frame.EvaluateExpression ("[my_class iCatchMyself]", options) + self.assertTrue (value.IsValid()) + self.assertTrue (value.GetError().Success() == True) + self.assertTrue (value.GetValueAsUnsigned() == 57) + self.check_after_call() + options.SetTrapExceptions(True) + + # Now set this unwind on error to false, and make sure that we stop where the exception was thrown + options.SetUnwindOnError(False) + value = frame.EvaluateExpression ("[my_class callMeIThrow]", options) + + + self.assertTrue (value.IsValid() and value.GetError().Success() == False) + self.check_after_call() diff --git a/packages/Python/lldbsuite/test/expression_command/call-throws/call-throws.m b/packages/Python/lldbsuite/test/expression_command/call-throws/call-throws.m new file mode 100644 index 0000000..a184718 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/call-throws/call-throws.m @@ -0,0 +1,47 @@ +#import + +@interface MyClass : NSObject +{ +} +- (int) callMeIThrow; +- (int) iCatchMyself; +@end + +@implementation MyClass +- (int) callMeIThrow +{ + NSException *e = [NSException + exceptionWithName:@"JustForTheHeckOfItException" + reason:@"I felt like it" + userInfo:nil]; + @throw e; + return 56; +} + +- (int) iCatchMyself +{ + int return_value = 55; + @try + { + return_value = [self callMeIThrow]; + } + @catch (NSException *e) + { + return_value = 57; + } + return return_value; +} +@end + +int +main () +{ + int return_value; + MyClass *my_class = [[MyClass alloc] init]; + + NSLog (@"I am about to throw."); + + return_value = [my_class iCatchMyself]; + + return return_value; +} diff --git a/packages/Python/lldbsuite/test/expression_command/char/Makefile b/packages/Python/lldbsuite/test/expression_command/char/Makefile new file mode 100644 index 0000000..8a7102e --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/char/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py b/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py new file mode 100644 index 0000000..90e847f --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py @@ -0,0 +1,69 @@ +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprCharTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + self.main_source = "main.cpp" + self.main_source_spec = lldb.SBFileSpec (self.main_source) + self.exe = os.path.join(os.getcwd(), "a.out") + + def do_test(self, dictionary=None): + """These basic expression commands should work as expected.""" + self.build(dictionary = dictionary) + + target = self.dbg.CreateTarget(self.exe) + self.assertTrue(target) + + breakpoint = target.BreakpointCreateBySourceRegex('// Break here', self.main_source_spec) + self.assertTrue(breakpoint) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple(None, None, self.get_process_working_directory()) + self.assertTrue(process) + + threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint) + self.assertEqual(len(threads), 1) + + frame = threads[0].GetFrameAtIndex(0) + + value = frame.EvaluateExpression("foo(c)") + self.assertTrue(value.IsValid()) + self.assertTrue(value.GetError().Success()) + self.assertEqual(value.GetValueAsSigned(0), 1) + + value = frame.EvaluateExpression("foo(sc)") + self.assertTrue(value.IsValid()) + self.assertTrue(value.GetError().Success()) + self.assertEqual(value.GetValueAsSigned(0), 2) + + value = frame.EvaluateExpression("foo(uc)") + self.assertTrue(value.IsValid()) + self.assertTrue(value.GetError().Success()) + self.assertEqual(value.GetValueAsSigned(0), 3) + + @expectedFailureWindows("llvm.org/pr21765") + def test_default_char(self): + self.do_test() + + @expectedFailureArch("arm", "llvm.org/pr23069") + @expectedFailureArch("aarch64", "llvm.org/pr23069") + @expectedFailureWindows("llvm.org/pr21765") + def test_signed_char(self): + self.do_test(dictionary={'CFLAGS_EXTRAS': '-fsigned-char'}) + + @expectedFailurei386("llvm.org/pr23069") + @expectedFailurex86_64("llvm.org/pr23069") + @expectedFailureWindows("llvm.org/pr21765") + def test_unsigned_char(self): + self.do_test(dictionary={'CFLAGS_EXTRAS': '-funsigned-char'}) diff --git a/packages/Python/lldbsuite/test/expression_command/char/main.cpp b/packages/Python/lldbsuite/test/expression_command/char/main.cpp new file mode 100644 index 0000000..c8b0beb --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/char/main.cpp @@ -0,0 +1,10 @@ +int foo(char c) { return 1; } +int foo(signed char c) { return 2; } +int foo(unsigned char c) { return 3; } + +int main() { + char c = 0; + signed char sc = 0; + unsigned char uc = 0; + return 0; // Break here +} diff --git a/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/Makefile b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/Makefile new file mode 100644 index 0000000..8a7102e --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py new file mode 100644 index 0000000..0430fa5 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py @@ -0,0 +1,82 @@ +"""Test that we are able to evaluate expressions when the inferior is blocked in a syscall""" + +from __future__ import print_function + + + +import os +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class ExprSyscallTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureWindows("llvm.org/pr21765") # Also getpid() is not a function on Windows anyway + def test_setpgid(self): + self.build() + self.expr_syscall() + + def expr_syscall(self): + exe = os.path.join(os.getcwd(), 'a.out') + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + listener = lldb.SBListener("my listener") + + # launch the inferior and don't wait for it to stop + self.dbg.SetAsync(True) + error = lldb.SBError() + process = target.Launch (listener, + None, # argv + None, # envp + None, # stdin_path + None, # stdout_path + None, # stderr_path + None, # working directory + 0, # launch flags + False, # Stop at entry + error) # error + + self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID) + + event = lldb.SBEvent() + + # Give the child enough time to reach the syscall, + # while clearing out all the pending events. + # The last WaitForEvent call will time out after 2 seconds. + while listener.WaitForEvent(2, event): + pass + + # now the process should be running (blocked in the syscall) + self.assertEqual(process.GetState(), lldb.eStateRunning, "Process is running") + + # send the process a signal + process.SendAsyncInterrupt() + while listener.WaitForEvent(2, event): + pass + + # as a result the process should stop + # in all likelihood we have stopped in the middle of the sleep() syscall + self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + thread = process.GetSelectedThread() + + # try evaluating a couple of expressions in this state + self.expect("expr release_flag = 1", substrs = [" = 1"]) + self.expect("print (int)getpid()", substrs = [str(process.GetProcessID())]) + + # and run the process to completion + process.Continue() + + # process all events + while listener.WaitForEvent(10, event): + new_state = lldb.SBProcess.GetStateFromEvent(event) + if new_state == lldb.eStateExited: + break + + self.assertEqual(process.GetState(), lldb.eStateExited) + self.assertEqual(process.GetExitStatus(), 0) diff --git a/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/main.cpp b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/main.cpp new file mode 100644 index 0000000..743b694 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/main.cpp @@ -0,0 +1,12 @@ +#include +#include + +volatile int release_flag = 0; + +int main(int argc, char const *argv[]) +{ + while (! release_flag) // Wait for debugger to attach + std::this_thread::sleep_for(std::chrono::seconds(3)); + + return 0; +} diff --git a/packages/Python/lldbsuite/test/expression_command/formatters/Makefile b/packages/Python/lldbsuite/test/expression_command/formatters/Makefile new file mode 100644 index 0000000..8a7102e --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/formatters/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py b/packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py new file mode 100644 index 0000000..3f47206 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py @@ -0,0 +1,167 @@ +""" +Test using LLDB data formatters with frozen objects coming from the expression parser. +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprFormattersTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.line = line_number('main.cpp', + '// Stop here') + + @skipIfFreeBSD # llvm.org/pr24691 skipping to avoid crashing the test runner + @expectedFailureFreeBSD('llvm.org/pr19011') # Newer Clang omits C1 complete object constructor + @expectedFailureFreeBSD('llvm.org/pr24691') # we hit an assertion in clang + @expectedFailureWindows("llvm.org/pr21765") + @skipIfTargetAndroid() # skipping to avoid crashing the test runner + @expectedFailureAndroid('llvm.org/pr24691') # we hit an assertion in clang + def test(self): + """Test expr + formatters for good interoperability.""" + self.build() + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type summary clear', check=False) + self.runCmd('type synthetic clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + """Test expr + formatters for good interoperability.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + self.runCmd("command script import formatters.py") + self.runCmd("command script import foosynth.py") + + if self.TraceOn(): + self.runCmd("frame variable foo1 --show-types") + self.runCmd("frame variable foo1.b --show-types") + self.runCmd("frame variable foo1.b.b_ref --show-types") + + self.expect("expression --show-types -- *(new foo(47))", + substrs = ['(int) a = 47', '(bar) b = {', '(int) i = 94', '(baz) b = {', '(int) k = 99']) + + self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") + + self.expect("expression new int(12)", + substrs = ['(int *) $', ' = 0x']) + + self.runCmd("type summary add -s \"${var%pointer} -> ${*var%decimal}\" \"int *\"") + + self.expect("expression new int(12)", + substrs = ['(int *) $', '= 0x', ' -> 12']) + + self.expect("expression foo1.a_ptr", + substrs = ['(int *) $', '= 0x', ' -> 13']) + + self.expect("expression foo1", + substrs = ['(foo) $', ' a = 12', 'a_ptr = ', ' -> 13','i = 24','i_ptr = ', ' -> 25']) + + self.expect("expression --ptr-depth=1 -- new foo(47)", + substrs = ['(foo *) $', 'a = 47','a_ptr = ', ' -> 48','i = 94','i_ptr = ', ' -> 95']) + + self.expect("expression foo2", + substrs = ['(foo) $', 'a = 121','a_ptr = ', ' -> 122','i = 242','i_ptr = ', ' -> 243']) + + object_name = self.res.GetOutput() + object_name = object_name[7:] + object_name = object_name[0:object_name.find(' =')] + + self.expect("frame variable foo2", + substrs = ['(foo)', 'foo2', 'a = 121','a_ptr = ', ' -> 122','i = 242','i_ptr = ', ' -> 243']) + + self.expect("expression $" + object_name, + substrs = ['(foo) $', 'a = 121','a_ptr = ', ' -> 122','i = 242','i_ptr = ', ' -> 243', 'h = 245','k = 247']) + + self.runCmd("type summary delete foo") + self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo") + + self.expect("expression --show-types -- $" + object_name, + substrs = ['(foo) $', ' = {', '(int) *i_ptr = 243']) + + self.runCmd("n") + self.runCmd("n") + + self.runCmd("type synthetic delete foo") + self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") + + self.expect("expression foo2", + substrs = ['(foo) $', 'a = 7777','a_ptr = ', ' -> 122','i = 242','i_ptr = ', ' -> 8888']) + + self.expect("expression $" + object_name + '.a', + substrs = ['7777']) + + self.expect("expression *$" + object_name + '.b.i_ptr', + substrs = ['8888']) + + self.expect("expression $" + object_name, + substrs = ['(foo) $', 'a = 121', 'a_ptr = ', ' -> 122', 'i = 242', 'i_ptr = ', ' -> 8888', 'h = 245','k = 247']) + + self.runCmd("type summary delete foo") + self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo") + + self.expect("expression --show-types -- $" + object_name, + substrs = ['(foo) $', ' = {', '(int) *i_ptr = 8888']) + + self.runCmd("n") + + self.runCmd("type synthetic delete foo") + self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") + + self.expect("expression $" + object_name, + substrs = ['(foo) $', 'a = 121','a_ptr = ', ' -> 122','i = 242', 'i_ptr = ', ' -> 8888','k = 247']) + + process = self.dbg.GetSelectedTarget().GetProcess() + thread = process.GetThreadAtIndex(0) + frame = thread.GetSelectedFrame() + + frozen = frame.EvaluateExpression("$" + object_name + ".a_ptr") + + a_data = frozen.GetPointeeData() + + error = lldb.SBError() + self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 122, '*a_ptr = 122') + + self.runCmd("n");self.runCmd("n");self.runCmd("n"); + + self.expect("frame variable numbers", + substrs = ['1','2','3','4','5']) + + self.expect("expression numbers", + substrs = ['1','2','3','4','5']) + + frozen = frame.EvaluateExpression("&numbers") + + a_data = frozen.GetPointeeData(0, 1) + + self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 1, 'numbers[0] == 1') + self.assertTrue(a_data.GetUnsignedInt32(error, 4) == 2, 'numbers[1] == 2') + self.assertTrue(a_data.GetUnsignedInt32(error, 8) == 3, 'numbers[2] == 3') + self.assertTrue(a_data.GetUnsignedInt32(error, 12) == 4, 'numbers[3] == 4') + self.assertTrue(a_data.GetUnsignedInt32(error, 16) == 5, 'numbers[4] == 5') + + frozen = frame.EvaluateExpression("numbers") + + a_data = frozen.GetData() + + self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 1, 'numbers[0] == 1') + self.assertTrue(a_data.GetUnsignedInt32(error, 4) == 2, 'numbers[1] == 2') + self.assertTrue(a_data.GetUnsignedInt32(error, 8) == 3, 'numbers[2] == 3') + self.assertTrue(a_data.GetUnsignedInt32(error, 12) == 4, 'numbers[3] == 4') + self.assertTrue(a_data.GetUnsignedInt32(error, 16) == 5, 'numbers[4] == 5') diff --git a/packages/Python/lldbsuite/test/expression_command/formatters/foosynth.py b/packages/Python/lldbsuite/test/expression_command/formatters/foosynth.py new file mode 100644 index 0000000..91c4d4a --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/formatters/foosynth.py @@ -0,0 +1,29 @@ +import lldb + +class FooSyntheticProvider: + def __init__(self,valobj,dict): + self.valobj = valobj; + self.update(); + + def update(self): + self.adjust_for_architecture() + + def num_children(self): + return 1; + + def get_child_at_index(self,index): + if index != 0: + return None; + return self.i_ptr.Dereference(); + + def get_child_index(self,name): + if name == "*i_ptr": + return 0; + return None; + + def adjust_for_architecture(self): + self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) + self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) + self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + self.bar = self.valobj.GetChildMemberWithName('b'); + self.i_ptr = self.bar.GetChildMemberWithName('i_ptr'); \ No newline at end of file diff --git a/packages/Python/lldbsuite/test/expression_command/formatters/formatters.py b/packages/Python/lldbsuite/test/expression_command/formatters/formatters.py new file mode 100644 index 0000000..ce922a8 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/formatters/formatters.py @@ -0,0 +1,17 @@ +def foo_SummaryProvider (valobj,dict): + a = valobj.GetChildMemberWithName('a'); + a_ptr = valobj.GetChildMemberWithName('a_ptr'); + bar = valobj.GetChildMemberWithName('b'); + i = bar.GetChildMemberWithName('i'); + i_ptr = bar.GetChildMemberWithName('i_ptr'); + b_ref = bar.GetChildMemberWithName('b_ref'); + b_ref_ptr = b_ref.AddressOf() + b_ref = b_ref_ptr.Dereference() + h = b_ref.GetChildMemberWithName('h'); + k = b_ref.GetChildMemberWithName('k'); + return 'a = ' + str(a.GetValueAsUnsigned(0)) + ', a_ptr = ' + \ + str(a_ptr.GetValueAsUnsigned(0)) + ' -> ' + str(a_ptr.Dereference().GetValueAsUnsigned(0)) + \ + ', i = ' + str(i.GetValueAsUnsigned(0)) + \ + ', i_ptr = ' + str(i_ptr.GetValueAsUnsigned(0)) + ' -> ' + str(i_ptr.Dereference().GetValueAsUnsigned(0)) + \ + ', b_ref = ' + str(b_ref.GetValueAsUnsigned(0)) + \ + ', h = ' + str(h.GetValueAsUnsigned(0)) + ' , k = ' + str(k.GetValueAsUnsigned(0)) \ No newline at end of file diff --git a/packages/Python/lldbsuite/test/expression_command/formatters/main.cpp b/packages/Python/lldbsuite/test/expression_command/formatters/main.cpp new file mode 100644 index 0000000..4c3b180 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/formatters/main.cpp @@ -0,0 +1,48 @@ +#include +#include + +struct baz + { + int h; + int k; + baz(int a, int b) : h(a), k(b) {} + }; + +struct bar + { + int i; + int* i_ptr; + baz b; + baz& b_ref; + bar(int x) : i(x),i_ptr(new int(x+1)),b(i+3,i+5),b_ref(b) {} + }; + +struct foo + { + int a; + int* a_ptr; + bar b; + + foo(int x) : a(x), + a_ptr(new int(x+1)), + b(2*x) {} + + }; + +int main(int argc, char** argv) +{ + foo foo1(12); + foo foo2(121); + + foo2.a = 7777; // Stop here + *(foo2.b.i_ptr) = 8888; + foo2.b.b.h = 9999; + + *(foo1.a_ptr) = 9999; + foo1.b.i = 9999; + + int numbers[5] = {1,2,3,4,5}; + + return 0; + +} \ No newline at end of file diff --git a/packages/Python/lldbsuite/test/expression_command/issue_11588/Makefile b/packages/Python/lldbsuite/test/expression_command/issue_11588/Makefile new file mode 100644 index 0000000..8a7102e --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/issue_11588/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py b/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py new file mode 100644 index 0000000..fdc981e --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py @@ -0,0 +1,77 @@ +""" +Test the solution to issue 11581. +valobj.AddressOf() returns None when an address is +expected in a SyntheticChildrenProvider +""" + +from __future__ import print_function + + + +import os, time +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class Issue11581TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureWindows("llvm.org/pr24778") + def test_11581_commands(self): + # This is the function to remove the custom commands in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type synthetic clear', check=False) + + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + """valobj.AddressOf() should return correct values.""" + self.build() + + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateBySourceRegex('Set breakpoint here.',lldb.SBFileSpec ("main.cpp", False)) + + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + self.assertTrue (process, "Created a process.") + self.assertTrue (process.GetState() == lldb.eStateStopped, "Stopped it too.") + + thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint) + self.assertTrue (len(thread_list) == 1) + thread = thread_list[0] + + self.runCmd("command script import --allow-reload s11588.py") + self.runCmd("type synthetic add --python-class s11588.Issue11581SyntheticProvider StgClosure") + + self.expect("expr --show-types -- *((StgClosure*)(r14-1))", + substrs = ["(StgClosure) $", + "(StgClosure *) &$","0x", + "addr = ", + "load_address = "]) + + # register r14 is an x86_64 extension let's skip this part of the test + # if we are on a different architecture + if self.getArchitecture() == 'x86_64': + target = lldb.debugger.GetSelectedTarget() + process = target.GetProcess() + frame = process.GetSelectedThread().GetSelectedFrame() + pointer = frame.FindVariable("r14") + addr = pointer.GetValueAsUnsigned(0) + self.assertTrue(addr != 0, "could not read pointer to StgClosure") + addr = addr - 1 + self.runCmd("register write r14 %d" % addr) + self.expect("register read r14", + substrs = ["0x",hex(addr)[2:].rstrip("L")]) # Remove trailing 'L' if it exists + self.expect("expr --show-types -- *(StgClosure*)$r14", + substrs = ["(StgClosure) $", + "(StgClosure *) &$","0x", + "addr = ", + "load_address = ", + hex(addr)[2:].rstrip("L"), + str(addr)]) diff --git a/packages/Python/lldbsuite/test/expression_command/issue_11588/main.cpp b/packages/Python/lldbsuite/test/expression_command/issue_11588/main.cpp new file mode 100644 index 0000000..4f9ea3a --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/issue_11588/main.cpp @@ -0,0 +1,54 @@ +// +// 11588.cpp +// + +#include + +class StgInfoTable {}; + +class StgHeader +{ +private: + StgInfoTable* info; +public: + StgHeader() + { + info = new StgInfoTable(); + } + ~StgHeader() + { + delete info; + } +}; + +class StgClosure +{ +private: + StgHeader header; + StgClosure* payload[1]; +public: + StgClosure(bool make_payload = true) + { + if (make_payload) + payload[0] = new StgClosure(false); + else + payload[0] = NULL; + } + ~StgClosure() + { + if (payload[0]) + delete payload[0]; + } +}; + +typedef unsigned long long int ptr_type; + +int main() +{ + StgClosure* r14_ = new StgClosure(); + r14_ = (StgClosure*)(((ptr_type)r14_ | 0x01)); // set the LSB to 1 for tagging + ptr_type r14 = (ptr_type)r14_; + int x = 0; + x = 3; + return (x-1); // Set breakpoint here. +} diff --git a/packages/Python/lldbsuite/test/expression_command/issue_11588/s11588.py b/packages/Python/lldbsuite/test/expression_command/issue_11588/s11588.py new file mode 100644 index 0000000..01bb09a --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/issue_11588/s11588.py @@ -0,0 +1,26 @@ +class Issue11581SyntheticProvider(object): + def __init__(self, valobj, dict): + self.valobj = valobj + self.addrOf = valobj.AddressOf() + self.addr = valobj.GetAddress() + self.load_address = valobj.GetLoadAddress() + + def num_children(self): + return 3; + + def get_child_at_index(self, index): + if index == 0: + return self.addrOf + if index == 1: + return self.valobj.CreateValueFromExpression("addr", str(self.addr)) + if index == 2: + return self.valobj.CreateValueFromExpression("load_address", str(self.load_address)) + + def get_child_index(self, name): + if name == "addrOf": + return 0 + if name == "addr": + return 1 + if name == "load_address": + return 2 + diff --git a/packages/Python/lldbsuite/test/expression_command/macros/Makefile b/packages/Python/lldbsuite/test/expression_command/macros/Makefile new file mode 100644 index 0000000..1ecd744 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/macros/Makefile @@ -0,0 +1,8 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +DEBUG_INFO_FLAG = -g3 + + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py b/packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py new file mode 100644 index 0000000..c3d6306 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py @@ -0,0 +1,106 @@ +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class TestMacros(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureClang("clang does not emit .debug_macro[.dwo] sections.") + @expectedFailureDwo("GCC produces multiple .debug_macro.dwo sections and the spec is unclear as to what it means") + @expectedFailureAll(hostoslist=["windows"], compiler="gcc", triple='.*-android') + def test_expr_with_macros(self): + self.build() + + # Get main source file + src_file = "main.cpp" + hdr_file = "macro1.h" + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "Main source file") + + # Get the path of the executable + cwd = os.getcwd() + exe_file = "a.out" + exe_path = os.path.join(cwd, exe_file) + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Set breakpoints + bp1 = target.BreakpointCreateBySourceRegex("Break here", src_file_spec) + self.assertTrue(bp1.IsValid() and bp1.GetNumLocations() >= 1, VALID_BREAKPOINT) + + # Launch the process + process = target.LaunchSimple(None, None, self.get_process_working_directory()) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) + + # Get frame for current thread + frame = thread.GetSelectedFrame() + + result = frame.EvaluateExpression("MACRO_1") + self.assertTrue(result.IsValid() and result.GetValue() == "100", "MACRO_1 = 100") + + result = frame.EvaluateExpression("MACRO_2") + self.assertTrue(result.IsValid() and result.GetValue() == "200", "MACRO_2 = 200") + + result = frame.EvaluateExpression("ONE") + self.assertTrue(result.IsValid() and result.GetValue() == "1", "ONE = 1") + + result = frame.EvaluateExpression("TWO") + self.assertTrue(result.IsValid() and result.GetValue() == "2", "TWO = 2") + + result = frame.EvaluateExpression("THREE") + self.assertTrue(result.IsValid() and result.GetValue() == "3", "THREE = 3") + + result = frame.EvaluateExpression("FOUR") + self.assertTrue(result.IsValid() and result.GetValue() == "4", "FOUR = 4") + + result = frame.EvaluateExpression("HUNDRED") + self.assertTrue(result.IsValid() and result.GetValue() == "100", "HUNDRED = 100") + + result = frame.EvaluateExpression("THOUSAND") + self.assertTrue(result.IsValid() and result.GetValue() == "1000", "THOUSAND = 1000") + + result = frame.EvaluateExpression("MILLION") + self.assertTrue(result.IsValid() and result.GetValue() == "1000000", "MILLION = 1000000") + + result = frame.EvaluateExpression("MAX(ONE, TWO)") + self.assertTrue(result.IsValid() and result.GetValue() == "2", "MAX(ONE, TWO) = 2") + + result = frame.EvaluateExpression("MAX(THREE, TWO)") + self.assertTrue(result.IsValid() and result.GetValue() == "3", "MAX(THREE, TWO) = 3") + + # Get the thread of the process + thread.StepOver() + + # Get frame for current thread + frame = thread.GetSelectedFrame() + + result = frame.EvaluateExpression("MACRO_2") + self.assertTrue(result.GetError().Fail(), "Printing MACRO_2 fails in the mail file") + + result = frame.EvaluateExpression("FOUR") + self.assertTrue(result.GetError().Fail(), "Printing FOUR fails in the main file") + + thread.StepInto() + + # Get frame for current thread + frame = thread.GetSelectedFrame() + + result = frame.EvaluateExpression("ONE") + self.assertTrue(result.IsValid() and result.GetValue() == "1", "ONE = 1") + + result = frame.EvaluateExpression("MAX(ONE, TWO)") + self.assertTrue(result.IsValid() and result.GetValue() == "2", "MAX(ONE, TWO) = 2") + + # This time, MACRO_1 and MACRO_2 are not visible. + result = frame.EvaluateExpression("MACRO_1") + self.assertTrue(result.GetError().Fail(), "Printing MACRO_1 fails in the header file") + + result = frame.EvaluateExpression("MACRO_2") + self.assertTrue(result.GetError().Fail(), "Printing MACRO_2 fails in the header file") diff --git a/packages/Python/lldbsuite/test/expression_command/macros/macro1.h b/packages/Python/lldbsuite/test/expression_command/macros/macro1.h new file mode 100644 index 0000000..e026bc0 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/macros/macro1.h @@ -0,0 +1,17 @@ + +#include "macro2.h" + +#define ONE 1 +#define TWO 2 +#define THREE 3 +#define FOUR 4 + +class Simple +{ +public: + int + Method() + { + return ONE + TWO; + }; +}; diff --git a/packages/Python/lldbsuite/test/expression_command/macros/macro2.h b/packages/Python/lldbsuite/test/expression_command/macros/macro2.h new file mode 100644 index 0000000..cec6efb --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/macros/macro2.h @@ -0,0 +1,8 @@ +#define HUNDRED 100 +#define THOUSAND 1000 +#define MILLION 1000000 + +#define MAX(a, b)\ +((a) > (b) ?\ + (a):\ + (b)) diff --git a/packages/Python/lldbsuite/test/expression_command/macros/main.cpp b/packages/Python/lldbsuite/test/expression_command/macros/main.cpp new file mode 100644 index 0000000..f2c2c10 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/macros/main.cpp @@ -0,0 +1,15 @@ +#include "macro1.h" + +#define MACRO_1 100 +#define MACRO_2 200 + +int +main () +{ + int a = ONE + TWO; // Break here + + #undef MACRO_2 + #undef FOUR + + return Simple().Method(); +} diff --git a/packages/Python/lldbsuite/test/expression_command/options/Makefile b/packages/Python/lldbsuite/test/expression_command/options/Makefile new file mode 100644 index 0000000..81ae6f6 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/options/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp foo.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/options/TestExprOptions.py b/packages/Python/lldbsuite/test/expression_command/options/TestExprOptions.py new file mode 100644 index 0000000..00c3482 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/options/TestExprOptions.py @@ -0,0 +1,76 @@ +""" +Test expression command options. + +Test cases: + +o test_expr_options: + Test expression command options. +""" + +from __future__ import print_function + + + +import os, time +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprOptionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + self.main_source = "main.cpp" + self.main_source_spec = lldb.SBFileSpec (self.main_source) + self.line = line_number('main.cpp', '// breakpoint_in_main') + self.exe = os.path.join(os.getcwd(), "a.out") + + def test_expr_options(self): + """These expression command options should work as expected.""" + self.build() + + # Set debugger into synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.exe) + self.assertTrue(target, VALID_TARGET) + + # Set breakpoints inside main. + breakpoint = target.BreakpointCreateBySourceRegex('// breakpoint_in_main', self.main_source_spec) + self.assertTrue(breakpoint) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple(None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint) + self.assertEqual(len(threads), 1) + + frame = threads[0].GetFrameAtIndex(0) + options = lldb.SBExpressionOptions() + + # test --language on C++ expression using the SB API's + + # Make sure we can evaluate a C++11 expression. + val = frame.EvaluateExpression('foo != nullptr') + self.assertTrue(val.IsValid()) + self.assertTrue(val.GetError().Success()) + self.DebugSBValue(val) + + # Make sure it still works if language is set to C++11: + options.SetLanguage(lldb.eLanguageTypeC_plus_plus_11) + val = frame.EvaluateExpression('foo != nullptr', options) + self.assertTrue(val.IsValid()) + self.assertTrue(val.GetError().Success()) + self.DebugSBValue(val) + + # Make sure it fails if language is set to C: + options.SetLanguage(lldb.eLanguageTypeC) + val = frame.EvaluateExpression('foo != nullptr', options) + self.assertTrue(val.IsValid()) + self.assertFalse(val.GetError().Success()) diff --git a/packages/Python/lldbsuite/test/expression_command/options/foo.cpp b/packages/Python/lldbsuite/test/expression_command/options/foo.cpp new file mode 100644 index 0000000..8a5a6a2 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/options/foo.cpp @@ -0,0 +1,11 @@ +namespace ns { + int func(void) + { + return 0; + } +} + +extern "C" int foo(void) +{ + return ns::func(); +} diff --git a/packages/Python/lldbsuite/test/expression_command/options/main.cpp b/packages/Python/lldbsuite/test/expression_command/options/main.cpp new file mode 100644 index 0000000..ecd9a90 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/options/main.cpp @@ -0,0 +1,15 @@ +extern "C" int foo(void); +static int static_value = 0; + +int +bar() +{ + static_value++; + return static_value; +} + +int main (int argc, char const *argv[]) +{ + bar(); // breakpoint_in_main + return foo(); +} diff --git a/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/Makefile b/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/Makefile new file mode 100644 index 0000000..8066198 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../make + +OBJC_SOURCES := main.m + +include $(LEVEL)/Makefile.rules +LDFLAGS += -framework Foundation -framework CloudKit + diff --git a/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py b/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py new file mode 100644 index 0000000..7b0707c --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py @@ -0,0 +1,50 @@ +""" +Test that we can p *objcObject +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class PersistObjCPointeeType(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.line = line_number('main.m','// break here') + + @skipUnlessDarwin + @expectedFailureAll( + bugnumber='http://llvm.org/pr23504', + oslist=['macosx'], compiler='clang', compiler_version=['<', '7.0.0']) + def test_with(self): + """Test that we can p *objcObject""" + self.build() + + def cleanup(): + pass + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + self.expect("p *self", substrs=['_sc_name = nil', + '_sc_name2 = nil', + '_sc_name3 = nil', + '_sc_name4 = nil', + '_sc_name5 = nil', + '_sc_name6 = nil', + '_sc_name7 = nil', + '_sc_name8 = nil']) diff --git a/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/main.m b/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/main.m new file mode 100644 index 0000000..a2b6b70 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/main.m @@ -0,0 +1,80 @@ +/* +clang -g ExtendSuperclass.m -o ExtendSuperclass -framework Foundation -framework ProtectedCloudStorage -F/System/Library/PrivateFrameworks/ -framework CloudKit && ./ExtendSuperclass +*/ +#include +#import +#import + +#define SuperClass CKDatabase + +@interface SubClass : SuperClass +@end + +// class extension +@interface SuperClass () +@property (nonatomic, strong) NSString *_sc_name; +@property (nonatomic, strong) NSString *_sc_name2; +@property (nonatomic, strong) NSString *_sc_name3; +@property (nonatomic, strong) NSString *_sc_name4; +@property (nonatomic, strong) NSString *_sc_name5; +@property (nonatomic, strong) NSString *_sc_name6; +@property (nonatomic, strong) NSString *_sc_name7; +@property (nonatomic, strong) NSString *_sc_name8; +@end + +@implementation SuperClass (MySuperClass) +- (id)initThatDoesNotAssert +{ + return [super init]; +} +@end + +@implementation SubClass +- (id)initThatDoesNotAssert +{ + assert(_sc_name == nil); + assert(_sc_name2 == nil); + assert(_sc_name3 == nil); + assert(_sc_name4 == nil); + assert(_sc_name5 == nil); + assert(_sc_name6 == nil); + assert(_sc_name7 == nil); + assert(_sc_name8 == nil); // break here + + if ((self = [super _initWithContainer:(CKContainer*)@"foo" scope:0xff])) { + assert(_sc_name == nil); + assert(_sc_name2 == nil); + assert(_sc_name3 == nil); + assert(_sc_name4 == nil); + assert(_sc_name5 == nil); + assert(_sc_name6 == nil); + assert(_sc_name7 == nil); + assert(_sc_name8 == nil); + + _sc_name = @"empty"; + } + return self; +} +@synthesize _sc_name; +@synthesize _sc_name2; +@synthesize _sc_name3; +@synthesize _sc_name4; +@synthesize _sc_name5; +@synthesize _sc_name6; +@synthesize _sc_name7; +@synthesize _sc_name8; +- (void)foo:(NSString*)bar { self._sc_name = bar; } +- (NSString*)description { return [NSString stringWithFormat:@"%p: %@", self, self._sc_name]; } +@end + +int main() +{ + SubClass *sc = [[SubClass alloc] initThatDoesNotAssert]; + NSLog(@"%@", sc); + [sc foo:@"bar"]; + NSLog(@"%@", sc); + sc._sc_name = @"bar2"; + NSLog(@"%@", sc); + NSLog(@"%@", sc._sc_name); + return 0; +} diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/Makefile b/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/Makefile new file mode 100644 index 0000000..db5f575 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules + + diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py b/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py new file mode 100644 index 0000000..9d7359fb --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py @@ -0,0 +1,41 @@ +""" +Test that we can have persistent pointer variables +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class PersistentPtrUpdateTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def test(self): + """Test that we can have persistent pointer variables""" + self.build() + + def cleanup(): + pass + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.runCmd('break set -p here') + + self.runCmd("run", RUN_SUCCEEDED) + + self.runCmd("expr void* $foo = 0") + + self.runCmd("continue") + + self.expect("expr $foo", substrs=['$foo','0x0']) diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/main.c b/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/main.c new file mode 100644 index 0000000..7334696 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/main.c @@ -0,0 +1,11 @@ +void* foo(void *p) +{ + return p; // break here +} + +int main() { + while (1) { + foo(0); + } + return 0; +} diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_types/Makefile b/packages/Python/lldbsuite/test/expression_command/persistent_types/Makefile new file mode 100644 index 0000000..0d70f25 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_types/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py b/packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py new file mode 100644 index 0000000..3ea5b70 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py @@ -0,0 +1,41 @@ +""" +Test that nested persistent types work. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * + +class NestedPersistentTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureWindows("llvm.org/pr21765") + def test_persistent_types(self): + """Test that nested persistent types work.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.runCmd("breakpoint set --name main") + + self.runCmd("run", RUN_SUCCEEDED) + + self.runCmd("expression struct $foo { int a; int b; };") + + self.runCmd("expression struct $bar { struct $foo start; struct $foo end; };") + + self.runCmd("expression struct $bar $my_bar = {{ 2, 3 }, { 4, 5 }};") + + self.expect("expression $my_bar", + substrs = ['a = 2', 'b = 3', 'a = 4', 'b = 5']) + + self.expect("expression $my_bar.start.b", + substrs = ['(int)', '3']) + + self.expect("expression $my_bar.end.b", + substrs = ['(int)', '5']) diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py b/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py new file mode 100644 index 0000000..47c6675 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py @@ -0,0 +1,57 @@ +""" +Test that lldb persistent types works correctly. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * + +class PersistenttypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureWindows("llvm.org/pr21765") + def test_persistent_types(self): + """Test that lldb persistent types works correctly.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.runCmd("breakpoint set --name main") + + self.runCmd("run", RUN_SUCCEEDED) + + self.runCmd("expression struct $foo { int a; int b; };") + + self.expect("expression struct $foo $my_foo; $my_foo.a = 2; $my_foo.b = 3;", + startstr = "(int) $0 = 3") + + self.expect("expression $my_foo", + substrs = ['a = 2', 'b = 3']) + + self.runCmd("expression typedef int $bar") + + self.expect("expression $bar i = 5; i", + startstr = "($bar) $1 = 5") + + self.runCmd("expression struct $foobar { char a; char b; char c; char d; };") + self.runCmd("next") + + self.expect("memory read foo -t $foobar", + substrs = ['($foobar) 0x', ' = ', "a = 'H'","b = 'e'","c = 'l'","d = 'l'"]) # persistent types are OK to use for memory read + + self.expect("memory read foo -t foobar", + substrs = ['($foobar) 0x', ' = ', "a = 'H'","b = 'e'","c = 'l'","d = 'l'"],matching=False,error=True) # the type name is $foobar, make sure we settle for nothing less + + self.expect("expression struct { int a; int b; } x = { 2, 3 }; x", + substrs = ['a = 2', 'b = 3']) + + self.expect("expression struct { int x; int y; int z; } object; object.y = 1; object.z = 3; object.x = 2; object", + substrs = ['x = 2', 'y = 1', 'z = 3']) + + self.expect("expression struct A { int x; int y; }; struct { struct A a; int z; } object; object.a.y = 1; object.z = 3; object.a.x = 2; object", + substrs = ['x = 2', 'y = 1', 'z = 3']) diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_types/main.c b/packages/Python/lldbsuite/test/expression_command/persistent_types/main.c new file mode 100644 index 0000000..9e26e61 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_types/main.c @@ -0,0 +1,14 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main (int argc, char const *argv[]) +{ + const char* foo = "Hello world"; + return 0; +} diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_variables/Makefile b/packages/Python/lldbsuite/test/expression_command/persistent_variables/Makefile new file mode 100644 index 0000000..0d70f25 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_variables/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_variables/TestPersistentVariables.py b/packages/Python/lldbsuite/test/expression_command/persistent_variables/TestPersistentVariables.py new file mode 100644 index 0000000..e148fcd --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_variables/TestPersistentVariables.py @@ -0,0 +1,54 @@ +""" +Test that lldb persistent variables works correctly. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * + +class PersistentVariablesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_persistent_variables(self): + """Test that lldb persistent variables works correctly.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.runCmd("breakpoint set --source-pattern-regexp break") + + self.runCmd("run", RUN_SUCCEEDED) + + self.runCmd("expression int $i = i") + + self.expect("expression $i == i", + startstr = "(bool) $0 = true") + + self.expect("expression $i + 1", + startstr = "(int) $1 = 6") + + self.expect("expression $i + 3", + startstr = "(int) $2 = 8") + + self.expect("expression $2 + $1", + startstr = "(int) $3 = 14") + + self.expect("expression $3", + startstr = "(int) $3 = 14") + + self.expect("expression $2", + startstr = "(int) $2 = 8") + + self.expect("expression (int)-2", + startstr = "(int) $4 = -2") + + self.expect("expression $4 > (int)31", + startstr = "(bool) $5 = false") + + self.expect("expression (long)$4", + startstr = "(long) $6 = -2") diff --git a/packages/Python/lldbsuite/test/expression_command/persistent_variables/main.c b/packages/Python/lldbsuite/test/expression_command/persistent_variables/main.c new file mode 100644 index 0000000..fd41471 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/persistent_variables/main.c @@ -0,0 +1,14 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main (int argc, char const *argv[]) +{ + int i = 5; + return 0; // Set breakpoint here +} diff --git a/packages/Python/lldbsuite/test/expression_command/po_verbosity/Makefile b/packages/Python/lldbsuite/test/expression_command/po_verbosity/Makefile new file mode 100644 index 0000000..4464e2e --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/po_verbosity/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../make + +OBJC_SOURCES := main.m + +include $(LEVEL)/Makefile.rules +LDFLAGS += -framework Cocoa diff --git a/packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py b/packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py new file mode 100644 index 0000000..e415b92 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py @@ -0,0 +1,61 @@ +""" +Test that the po command acts correctly. +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class PoVerbosityTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.line = line_number('main.m', + '// Stop here') + + @skipUnlessDarwin + def test(self): + """Test that the po command acts correctly.""" + self.build() + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type summary clear', check=False) + self.runCmd('type synthetic clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + """Test expr + formatters for good interoperability.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + self.expect("expr -O -v -- foo", + substrs = ['(id) $',' = 0x', '1 = 2','2 = 3;']) + self.expect("expr -O -vfull -- foo", + substrs = ['(id) $',' = 0x', '1 = 2','2 = 3;']) + self.expect("expr -O -- foo",matching=False, + substrs = ['(id) $']) + + self.expect("expr -O -- 22",matching=False, + substrs = ['(int) $']) + self.expect("expr -O -- 22", + substrs = ['22']) + + self.expect("expr -O -vfull -- 22", + substrs = ['(int) $', ' = 22']) + + self.expect("expr -O -v -- 22", + substrs = ['(int) $', ' = 22']) diff --git a/packages/Python/lldbsuite/test/expression_command/po_verbosity/main.m b/packages/Python/lldbsuite/test/expression_command/po_verbosity/main.m new file mode 100644 index 0000000..3dbb024 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/po_verbosity/main.m @@ -0,0 +1,9 @@ +#import + +int main() +{ + [NSString initialize]; + id foo = @{@1 : @2, @2 : @3}; + int x = 34; + return 0; // Stop here +} diff --git a/packages/Python/lldbsuite/test/expression_command/radar_8638051/Makefile b/packages/Python/lldbsuite/test/expression_command/radar_8638051/Makefile new file mode 100644 index 0000000..0d70f25 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_8638051/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/radar_8638051/Test8638051.py b/packages/Python/lldbsuite/test/expression_command/radar_8638051/Test8638051.py new file mode 100644 index 0000000..302b14b --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_8638051/Test8638051.py @@ -0,0 +1,39 @@ +""" +Test the robustness of lldb expression parser. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * + +class Radar8638051TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_expr_commands(self): + """The following expression commands should not crash.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.runCmd("breakpoint set -n c") + + self.runCmd("run", RUN_SUCCEEDED) + + self.expect("expression val", + startstr = "(int) $0 = 1") + # (int) $0 = 1 + + self.expect("expression *(&val)", + startstr = "(int) $1 = 1") + # (int) $1 = 1 + + # rdar://problem/8638051 + # lldb expression command: Could this crash be avoided + self.expect("expression &val", + startstr = "(int *) $2 = ") + # (int *) $2 = 0x.... diff --git a/packages/Python/lldbsuite/test/expression_command/radar_8638051/main.c b/packages/Python/lldbsuite/test/expression_command/radar_8638051/main.c new file mode 100644 index 0000000..1329fd69 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_8638051/main.c @@ -0,0 +1,54 @@ +//===-- 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 + +// This simple program is to demonstrate the capability of the lldb command +// "breakpoint command add" to add a set of commands to a breakpoint to be +// executed when the breakpoint is hit. +// +// In particular, we want to break within c(), but only if the immediate caller +// is a(). + +int a(int); +int b(int); +int c(int); + +int a(int val) +{ + if (val <= 1) + return b(val); + else if (val >= 3) + return c(val); // Find the line number where c's parent frame is a here. + + return val; +} + +int b(int val) +{ + return c(val); +} + +int c(int val) +{ + return val + 3; +} + +int main (int argc, char const *argv[]) +{ + int A1 = a(1); // a(1) -> b(1) -> c(1) + printf("a(1) returns %d\n", A1); + + int B2 = b(2); // b(2) -> c(2) + printf("b(2) returns %d\n", B2); + + int A3 = a(3); // a(3) -> c(3) + printf("a(3) returns %d\n", A3); + + return 0; +} diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9531204/Makefile b/packages/Python/lldbsuite/test/expression_command/radar_9531204/Makefile new file mode 100644 index 0000000..0d70f25 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_9531204/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py b/packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py new file mode 100644 index 0000000..fb16d2a --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py @@ -0,0 +1,42 @@ +""" +The evaluating printf(...) after break stop and then up a stack frame. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class Radar9531204TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # rdar://problem/9531204 + @expectedFailureWindows("llvm.org/pr21765") + def test_expr_commands(self): + """The evaluating printf(...) after break stop and then up a stack frame.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_symbol (self, 'foo', sym_exact=True, num_expected_locations=1) + + self.runCmd("run", RUN_SUCCEEDED) + + self.runCmd("frame variable") + + # This works fine. + self.runCmd('expression (int)printf("value is: %d.\\n", value);') + + # rdar://problem/9531204 + # "Error dematerializing struct" error when evaluating expressions "up" on the stack + self.runCmd('up') # frame select -r 1 + + self.runCmd("frame variable") + + # This does not currently. + self.runCmd('expression (int)printf("argc is: %d.\\n", argc)') diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9531204/main.c b/packages/Python/lldbsuite/test/expression_command/radar_9531204/main.c new file mode 100644 index 0000000..2bf05f2 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_9531204/main.c @@ -0,0 +1,25 @@ +//===-- 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 + +// breakpoint set -n foo +// +// +int foo (int value) +{ + printf ("I got the value: %d.\n", value); + return 0; +} + +int main (int argc, char **argv) +{ + foo (argc); + printf ("Hello there: %d.\n", argc); + return 0; +} diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9673664/Makefile b/packages/Python/lldbsuite/test/expression_command/radar_9673664/Makefile new file mode 100644 index 0000000..0d70f25 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_9673664/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py b/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py new file mode 100644 index 0000000..ce3e51d --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py @@ -0,0 +1,41 @@ +""" +Test example snippets from the lldb 'help expression' output. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class Radar9673644TestCase(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.main_source = "main.c" + self.line = line_number(self.main_source, '// Set breakpoint here.') + + @expectedFailureWindows("llvm.org/pr21765") + def test_expr_commands(self): + """The following expression commands should just work.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, self.main_source, self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # rdar://problem/9673664 lldb expression evaluation problem + + self.expect('expr char c[] = "foo"; c[0]', + substrs = ["'f'"]) + # runCmd: expr char c[] = "foo"; c[0] + # output: (char) $0 = 'f' diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9673664/main.c b/packages/Python/lldbsuite/test/expression_command/radar_9673664/main.c new file mode 100644 index 0000000..934abdf --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/radar_9673664/main.c @@ -0,0 +1,16 @@ +//===-- 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 + +int main (int argc, char const *argv[]) +{ + printf("Hello, world.\n"); // Set breakpoint here. + + return 0; +} diff --git a/packages/Python/lldbsuite/test/expression_command/test/Makefile b/packages/Python/lldbsuite/test/expression_command/test/Makefile new file mode 100644 index 0000000..8a7102e --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/test/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py b/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py new file mode 100644 index 0000000..ec3e7f9 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/test/TestExprs.py @@ -0,0 +1,248 @@ +""" +Test many basic expression commands and SBFrame.EvaluateExpression() API. + +Test cases: + +o test_many_expr_commands: + Test many basic expression commands. +o test_evaluate_expression_python: + Use Python APIs (SBFrame.EvaluateExpression()) to evaluate expressions. +o test_expr_commands_can_handle_quotes: + Throw some expression commands with quotes at lldb. +""" + +from __future__ import print_function + + + +import unittest2 + +import os, time +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class BasicExprCommandsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.c. + self.line = line_number('main.cpp', + '// Please test many expressions while stopped at this line:') + + # Disable confirmation prompt to avoid infinite wait + self.runCmd("settings set auto-confirm true") + self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm")) + + + def build_and_run(self): + """These basic expression commands should work as expected.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False) + + self.runCmd("run", RUN_SUCCEEDED) + + @unittest2.expectedFailure("llvm.org/pr17135 APFloat::toString does not identify the correct (i.e. least) precision.") + def test_floating_point_expr_commands(self): + self.build_and_run() + + self.expect("expression 2.234f", + patterns = ["\(float\) \$.* = 2\.234"]) + # (float) $2 = 2.234 + + @expectedFailureWindows("llvm.org/pr21765") + def test_many_expr_commands(self): + self.build_and_run() + + self.expect("expression 2", + patterns = ["\(int\) \$.* = 2"]) + # (int) $0 = 1 + + self.expect("expression 2ull", + patterns = ["\(unsigned long long\) \$.* = 2"]) + # (unsigned long long) $1 = 2 + + self.expect("expression 0.5f", + patterns = ["\(float\) \$.* = 0\.5"]) + # (float) $2 = 0.5 + + self.expect("expression 2.234", + patterns = ["\(double\) \$.* = 2\.234"]) + # (double) $3 = 2.234 + + self.expect("expression 2+3", + patterns = ["\(int\) \$.* = 5"]) + # (int) $4 = 5 + + self.expect("expression argc", + patterns = ["\(int\) \$.* = 1"]) + # (int) $5 = 1 + + self.expect("expression argc + 22", + patterns = ["\(int\) \$.* = 23"]) + # (int) $6 = 23 + + self.expect("expression argv", + patterns = ["\(const char \*\*\) \$.* = 0x"]) + # (const char *) $7 = ... + + self.expect("expression argv[0]", + substrs = ["(const char *)", + "a.out"]) + # (const char *) $8 = 0x... "/Volumes/data/lldb/svn/trunk/test/expression_command/test/a.out" + + @add_test_categories(['pyapi']) + @expectedFailureWindows # Test crashes + def test_evaluate_expression_python(self): + """Test SBFrame.EvaluateExpression() API for evaluating an expression.""" + self.build() + + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint. + filespec = lldb.SBFileSpec("main.cpp", False) + breakpoint = target.BreakpointCreateByLocation(filespec, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Verify the breakpoint just created. + self.expect(str(breakpoint), BREAKPOINT_CREATED, exe=False, + substrs = ['main.cpp', + str(self.line)]) + + # Launch the process, and do not stop at the entry point. + # Pass 'X Y Z' as the args, which makes argc == 4. + process = target.LaunchSimple (['X', 'Y', 'Z'], None, self.get_process_working_directory()) + + if not process: + self.fail("SBTarget.LaunchProcess() failed") + + if process.GetState() != lldb.eStateStopped: + self.fail("Process should be in the 'stopped' state, " + "instead the actual state is: '%s'" % + lldbutil.state_type_to_str(process.GetState())) + + # The stop reason of the thread should be breakpoint. + thread = process.GetThreadAtIndex(0) + if thread.GetStopReason() != lldb.eStopReasonBreakpoint: + from lldbsuite.test.lldbutil import stop_reason_to_str + self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % + stop_reason_to_str(thread.GetStopReason())) + + # The filename of frame #0 should be 'main.cpp' and function is main. + self.expect(lldbutil.get_filenames(thread)[0], + "Break correctly at main.cpp", exe=False, + startstr = "main.cpp") + self.expect(lldbutil.get_function_names(thread)[0], + "Break correctly at main()", exe=False, + startstr = "main") + + # We should be stopped on the breakpoint with a hit count of 1. + self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) + + # + # Use Python API to evaluate expressions while stopped in a stack frame. + # + frame = thread.GetFrameAtIndex(0) + + val = frame.EvaluateExpression("2.234") + self.expect(val.GetValue(), "2.345 evaluated correctly", exe=False, + startstr = "2.234") + self.expect(val.GetTypeName(), "2.345 evaluated correctly", exe=False, + startstr = "double") + self.DebugSBValue(val) + + val = frame.EvaluateExpression("argc") + self.expect(val.GetValue(), "Argc evaluated correctly", exe=False, + startstr = "4") + self.DebugSBValue(val) + + val = frame.EvaluateExpression("*argv[1]") + self.expect(val.GetValue(), "Argv[1] evaluated correctly", exe=False, + startstr = "'X'") + self.DebugSBValue(val) + + val = frame.EvaluateExpression("*argv[2]") + self.expect(val.GetValue(), "Argv[2] evaluated correctly", exe=False, + startstr = "'Y'") + self.DebugSBValue(val) + + val = frame.EvaluateExpression("*argv[3]") + self.expect(val.GetValue(), "Argv[3] evaluated correctly", exe=False, + startstr = "'Z'") + self.DebugSBValue(val) + + callee_break = target.BreakpointCreateByName ("a_function_to_call", None) + self.assertTrue(callee_break.GetNumLocations() > 0) + + # Make sure ignoring breakpoints works from the command line: + self.expect("expression -i true -- a_function_to_call()", + substrs = ['(int) $', ' 1']) + self.assertTrue (callee_break.GetHitCount() == 1) + + # Now try ignoring breakpoints using the SB API's: + options = lldb.SBExpressionOptions() + options.SetIgnoreBreakpoints(True) + value = frame.EvaluateExpression('a_function_to_call()', options) + self.assertTrue (value.IsValid()) + self.assertTrue (value.GetValueAsSigned(0) == 2) + self.assertTrue (callee_break.GetHitCount() == 2) + + # rdar://problem/8686536 + # CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands + @expectedFailureWindows("llvm.org/pr21765") + def test_expr_commands_can_handle_quotes(self): + """Throw some expression commands with quotes at lldb.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line, num_expected_locations=1,loc_exact=False) + + self.runCmd("run", RUN_SUCCEEDED) + + # runCmd: expression 'a' + # output: (char) $0 = 'a' + self.expect("expression 'a'", + substrs = ['(char) $', + "'a'"]) + + # runCmd: expression (int) printf ("\n\n\tHello there!\n") + # output: (int) $1 = 16 + self.expect(r'''expression (int) printf ("\n\n\tHello there!\n")''', + substrs = ['(int) $', + '16']) + + # runCmd: expression (int) printf("\t\x68\n") + # output: (int) $2 = 3 + self.expect(r'''expression (int) printf("\t\x68\n")''', + substrs = ['(int) $', + '3']) + + # runCmd: expression (int) printf("\"\n") + # output: (int) $3 = 2 + self.expect(r'''expression (int) printf("\"\n")''', + substrs = ['(int) $', + '2']) + + # runCmd: expression (int) printf("'\n") + # output: (int) $4 = 2 + self.expect(r'''expression (int) printf("'\n")''', + substrs = ['(int) $', + '2']) + + # runCmd: command alias print_hi expression (int) printf ("\n\tHi!\n") + # output: + self.runCmd(r'''command alias print_hi expression (int) printf ("\n\tHi!\n")''') + # This fails currently. + self.expect('print_hi', + substrs = ['(int) $', + '6']) diff --git a/packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py b/packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py new file mode 100644 index 0000000..578a037 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py @@ -0,0 +1,60 @@ +""" +Test some more expression commands. +""" + +from __future__ import print_function + + + +import os +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprCommands2TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.c. + self.line = line_number('main.cpp', + '// Please test many expressions while stopped at this line:') + + @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows") + def test_more_expr_commands(self): + """Test some more expression commands.""" + self.build() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line, num_expected_locations=1,loc_exact=False) + + self.runCmd("run", RUN_SUCCEEDED) + + # Does static casting work? + self.expect("expression (int*)argv", + startstr = "(int *) $0 = 0x") + # (int *) $0 = 0x00007fff5fbff258 + + # Do anonymous symbols work? + self.expect("expression ((char**)environ)[0]", + startstr = "(char *) $1 = 0x") + # (char *) $1 = 0x00007fff5fbff298 "Apple_PubSub_Socket_Render=/tmp/launch-7AEsUD/Render" + + # Do return values containing the contents of expression locals work? + self.expect("expression int i = 5; i", + startstr = "(int) $2 = 5") + # (int) $2 = 5 + self.expect("expression $2 + 1", + startstr = "(int) $3 = 6") + # (int) $3 = 6 + + # Do return values containing the results of static expressions work? + self.expect("expression 20 + 3", + startstr = "(int) $4 = 23") + # (int) $4 = 5 + self.expect("expression $4 + 1", + startstr = "(int) $5 = 24") + # (int) $5 = 6 diff --git a/packages/Python/lldbsuite/test/expression_command/test/main.cpp b/packages/Python/lldbsuite/test/expression_command/test/main.cpp new file mode 100644 index 0000000..22208a8 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/test/main.cpp @@ -0,0 +1,44 @@ +#include + +static int static_value = 0; + +int +a_function_to_call() +{ + static_value++; + return static_value; +} + +int main (int argc, char const *argv[]) +{ + printf ("Hello world!\n"); + puts ("hello"); + // Please test many expressions while stopped at this line: +#if 0 + expression 'a' // make sure character constant makes it down (this is broken: ) + expression 2 // Test int + expression 2ull // Test unsigned long long + expression 2.234f // Test float constants + expression 2.234 // Test double constants + expression 2+3 + expression argc + expression argc + 22 + expression argv + expression argv[0] + expression argv[1] + expression argv[-1] + expression puts("bonjour") // Test constant strings... + expression printf("\t\x68\n") // Test constant strings that contain the \xXX (TAB, 'h', '\n' should be printed) (this is broken: ) + expression printf("\"\n") // Test constant strings that contains an escaped double quote char (this is broken: ) + expression printf("\'\n") // Test constant strings that contains an escaped single quote char (this is broken: ) + expression printf ("one: %i\n", 1) + expression printf ("1.234 as float: %f\n", 1.234f) + expression printf ("1.234 as double: %g\n", 1.234) + expression printf ("one: %i, two: %llu\n", 1, 2ull) + expression printf ("two: %llu, one: %i\n", 2ull, 1) + expression random() % 255l +#endif + + a_function_to_call(); + return 0; +} diff --git a/packages/Python/lldbsuite/test/expression_command/timeout/Makefile b/packages/Python/lldbsuite/test/expression_command/timeout/Makefile new file mode 100644 index 0000000..c9cff41 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/timeout/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := wait-a-while.cpp + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py b/packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py new file mode 100644 index 0000000..a602afc --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py @@ -0,0 +1,92 @@ +""" +Test calling a function that waits a while, and make sure the timeout option to expr works. +""" + +from __future__ import print_function + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprCommandWithTimeoutsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + self.main_source = "wait-a-while.cpp" + self.main_source_spec = lldb.SBFileSpec (self.main_source) + + + @expectedFlakeyFreeBSD("llvm.org/pr19605") + @expectedFlakeyLinux("llvm.org/pr20275") + @expectedFailureWindows("llvm.org/pr21765") + def test(self): + """Test calling std::String member function.""" + self.build() + + exe_name = "a.out" + exe = os.path.join(os.getcwd(), exe_name) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateBySourceRegex('stop here in main.',self.main_source_spec) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + self.runCmd("breakpoint list") + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # Frame #0 should be on self.step_out_of_malloc. + threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint) + + self.assertTrue(len(threads) == 1) + thread = threads[0] + + # First set the timeout too short, and make sure we fail. + options = lldb.SBExpressionOptions() + options.SetTimeoutInMicroSeconds(10) + options.SetUnwindOnError(True) + + frame = thread.GetFrameAtIndex(0) + + value = frame.EvaluateExpression ("wait_a_while (200000)", options) + self.assertTrue (value.IsValid()) + self.assertFalse (value.GetError().Success()) + + # Now do the same thing with the command line command, and make sure it works too. + interp = self.dbg.GetCommandInterpreter() + + result = lldb.SBCommandReturnObject() + return_value = interp.HandleCommand ("expr -t 100 -u true -- wait_a_while(200000)", result) + self.assertTrue (return_value == lldb.eReturnStatusFailed) + + # Okay, now do it again with long enough time outs: + + options.SetTimeoutInMicroSeconds(1000000) + value = frame.EvaluateExpression ("wait_a_while (1000)", options) + self.assertTrue(value.IsValid()) + self.assertTrue (value.GetError().Success() == True) + + # Now do the same thingwith the command line command, and make sure it works too. + interp = self.dbg.GetCommandInterpreter() + + result = lldb.SBCommandReturnObject() + return_value = interp.HandleCommand ("expr -t 1000000 -u true -- wait_a_while(1000)", result) + self.assertTrue(return_value == lldb.eReturnStatusSuccessFinishResult) + + + # Finally set the one thread timeout and make sure that doesn't change things much: + + options.SetTimeoutInMicroSeconds(1000000) + options.SetOneThreadTimeoutInMicroSeconds(500000) + value = frame.EvaluateExpression ("wait_a_while (1000)", options) + self.assertTrue(value.IsValid()) + self.assertTrue (value.GetError().Success() == True) diff --git a/packages/Python/lldbsuite/test/expression_command/timeout/wait-a-while.cpp b/packages/Python/lldbsuite/test/expression_command/timeout/wait-a-while.cpp new file mode 100644 index 0000000..ac37c5d --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/timeout/wait-a-while.cpp @@ -0,0 +1,35 @@ +#include +#include + +#include +#include + + +int +wait_a_while (int microseconds) +{ + int num_times = 0; + auto end_time = std::chrono::system_clock::now() + std::chrono::microseconds(microseconds); + + while (1) + { + num_times++; + auto wait_time = end_time - std::chrono::system_clock::now(); + + std::this_thread::sleep_for(wait_time); + if (std::chrono::system_clock::now() > end_time) + break; + } + return num_times; +} + +int +main (int argc, char **argv) +{ + printf ("stop here in main.\n"); + int num_times = wait_a_while (argc * 1000); + printf ("Done, took %d times.\n", num_times); + + return 0; + +} diff --git a/packages/Python/lldbsuite/test/expression_command/two-files/Makefile b/packages/Python/lldbsuite/test/expression_command/two-files/Makefile new file mode 100644 index 0000000..5974461 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/two-files/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../make + +OBJC_SOURCES := main.m foo.m + +include $(LEVEL)/Makefile.rules + +LDFLAGS += -framework Foundation \ No newline at end of file diff --git a/packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py b/packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py new file mode 100644 index 0000000..5b02335 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py @@ -0,0 +1,39 @@ +""" +Regression test for : + +The expression parser's type search only looks in the current compilation unit for types. +""" + +from __future__ import print_function + + + +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class ObjCTypeQueryTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.m. + self.line = line_number('main.m', + "// Set breakpoint here, then do 'expr (NSArray*)array_token'.") + + @skipUnlessDarwin + def test(self): + """The expression parser's type search should be wider than the current compilation unit.""" + self.build() + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # Now do a NSArry type query from the 'main.m' compile uint. + self.expect("expression (NSArray*)array_token", + substrs = ['(NSArray *) $0 = 0x']) + # (NSArray *) $0 = 0x00007fff70118398 diff --git a/packages/Python/lldbsuite/test/expression_command/two-files/foo.m b/packages/Python/lldbsuite/test/expression_command/two-files/foo.m new file mode 100644 index 0000000..1609ebd --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/two-files/foo.m @@ -0,0 +1,28 @@ +#import + +NSMutableArray * +GetArray () +{ + static NSMutableArray *the_array = NULL; + if (the_array == NULL) + the_array = [[NSMutableArray alloc] init]; + return the_array; +} + +int +AddElement (char *value) +{ + NSString *element = [NSString stringWithUTF8String: value]; + int cur_elem = [GetArray() count]; + [GetArray() addObject: element]; + return cur_elem; +} + +const char * +GetElement (int idx) +{ + if (idx >= [GetArray() count]) + return NULL; + else + return [[GetArray() objectAtIndex: idx] UTF8String]; +} diff --git a/packages/Python/lldbsuite/test/expression_command/two-files/main.m b/packages/Python/lldbsuite/test/expression_command/two-files/main.m new file mode 100644 index 0000000..3f57383 --- /dev/null +++ b/packages/Python/lldbsuite/test/expression_command/two-files/main.m @@ -0,0 +1,22 @@ +#import +#include + +extern int AddElement (char *value); +extern char *GetElement (int idx); +extern void *GetArray(); + +int +main () +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + int idx = AddElement ("some string"); + void *array_token = GetArray(); + + char *string = GetElement (0); // Set breakpoint here, then do 'expr (NSArray*)array_token'. + if (string) + printf ("This: %s.\n", string); + + [pool release]; + return 0; +} -- cgit v1.1