aboutsummaryrefslogtreecommitdiff
path: root/packages/Python/lldbsuite/test/expression_command
diff options
context:
space:
mode:
Diffstat (limited to 'packages/Python/lldbsuite/test/expression_command')
-rw-r--r--packages/Python/lldbsuite/test/expression_command/.categories1
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-function/Makefile15
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py43
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-function/TestCallStopAndContinue.py46
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-function/TestCallUserDefinedFunction.py52
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-function/main.cpp53
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-restarts/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py139
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-restarts/lotta-signals.c61
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-throws/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py112
-rw-r--r--packages/Python/lldbsuite/test/expression_command/call-throws/call-throws.m47
-rw-r--r--packages/Python/lldbsuite/test/expression_command/char/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py69
-rw-r--r--packages/Python/lldbsuite/test/expression_command/char/main.cpp10
-rw-r--r--packages/Python/lldbsuite/test/expression_command/expr-in-syscall/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/expr-in-syscall/TestExpressionInSyscall.py82
-rw-r--r--packages/Python/lldbsuite/test/expression_command/expr-in-syscall/main.cpp12
-rw-r--r--packages/Python/lldbsuite/test/expression_command/formatters/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/formatters/TestFormatters.py167
-rw-r--r--packages/Python/lldbsuite/test/expression_command/formatters/foosynth.py29
-rw-r--r--packages/Python/lldbsuite/test/expression_command/formatters/formatters.py17
-rw-r--r--packages/Python/lldbsuite/test/expression_command/formatters/main.cpp48
-rw-r--r--packages/Python/lldbsuite/test/expression_command/issue_11588/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py77
-rw-r--r--packages/Python/lldbsuite/test/expression_command/issue_11588/main.cpp54
-rw-r--r--packages/Python/lldbsuite/test/expression_command/issue_11588/s11588.py26
-rw-r--r--packages/Python/lldbsuite/test/expression_command/macros/Makefile8
-rw-r--r--packages/Python/lldbsuite/test/expression_command/macros/TestMacros.py106
-rw-r--r--packages/Python/lldbsuite/test/expression_command/macros/macro1.h17
-rw-r--r--packages/Python/lldbsuite/test/expression_command/macros/macro2.h8
-rw-r--r--packages/Python/lldbsuite/test/expression_command/macros/main.cpp15
-rw-r--r--packages/Python/lldbsuite/test/expression_command/options/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/options/TestExprOptions.py76
-rw-r--r--packages/Python/lldbsuite/test/expression_command/options/foo.cpp11
-rw-r--r--packages/Python/lldbsuite/test/expression_command/options/main.cpp15
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py50
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persist_objc_pointeetype/main.m80
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py41
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_ptr_update/main.c11
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_types/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_types/TestNestedPersistentTypes.py41
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py57
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_types/main.c14
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_variables/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_variables/TestPersistentVariables.py54
-rw-r--r--packages/Python/lldbsuite/test/expression_command/persistent_variables/main.c14
-rw-r--r--packages/Python/lldbsuite/test/expression_command/po_verbosity/Makefile6
-rw-r--r--packages/Python/lldbsuite/test/expression_command/po_verbosity/TestPoVerbosity.py61
-rw-r--r--packages/Python/lldbsuite/test/expression_command/po_verbosity/main.m9
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_8638051/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_8638051/Test8638051.py39
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_8638051/main.c54
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_9531204/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_9531204/TestPrintfAfterUp.py42
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_9531204/main.c25
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_9673664/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py41
-rw-r--r--packages/Python/lldbsuite/test/expression_command/radar_9673664/main.c16
-rw-r--r--packages/Python/lldbsuite/test/expression_command/test/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/test/TestExprs.py248
-rw-r--r--packages/Python/lldbsuite/test/expression_command/test/TestExprs2.py60
-rw-r--r--packages/Python/lldbsuite/test/expression_command/test/main.cpp44
-rw-r--r--packages/Python/lldbsuite/test/expression_command/timeout/Makefile5
-rw-r--r--packages/Python/lldbsuite/test/expression_command/timeout/TestCallWithTimeout.py92
-rw-r--r--packages/Python/lldbsuite/test/expression_command/timeout/wait-a-while.cpp35
-rw-r--r--packages/Python/lldbsuite/test/expression_command/two-files/Makefile7
-rw-r--r--packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py39
-rw-r--r--packages/Python/lldbsuite/test/expression_command/two-files/foo.m28
-rw-r--r--packages/Python/lldbsuite/test/expression_command/two-files/main.m22
72 files changed, 2731 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/expression_command/.categories b/packages/Python/lldbsuite/test/expression_command/.categories
new file mode 100644
index 000000000000..897e40a99dda
--- /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 000000000000..d4b82b3db276
--- /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 000000000000..3756b4a8cea4
--- /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 000000000000..f6d63885248a
--- /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 000000000000..9138af0b0b47
--- /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 000000000000..9b494c712bcc
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/call-function/main.cpp
@@ -0,0 +1,53 @@
+#include <iostream>
+#include <string>
+#include <cstring>
+
+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 000000000000..1c93ae1de439
--- /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 000000000000..abf48742567d
--- /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 000000000000..f5c15b41e2de
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/call-restarts/lotta-signals.c
@@ -0,0 +1,61 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+
+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 000000000000..ac07b31c48cc
--- /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 000000000000..0e766ac2953a
--- /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 000000000000..a184718be7dd
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/call-throws/call-throws.m
@@ -0,0 +1,47 @@
+#import <Foundation/Foundation.h>
+
+@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 000000000000..8a7102e347af
--- /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 000000000000..90e847fd5fa2
--- /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 000000000000..c8b0beb1b355
--- /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 000000000000..8a7102e347af
--- /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 000000000000..0430fa55f995
--- /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 000000000000..743b69434d5f
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/expr-in-syscall/main.cpp
@@ -0,0 +1,12 @@
+#include <chrono>
+#include <thread>
+
+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 000000000000..8a7102e347af
--- /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 000000000000..3f47206480c3
--- /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 000000000000..91c4d4a84c62
--- /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 000000000000..ce922a8f911d
--- /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 000000000000..4c3b180f3709
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/formatters/main.cpp
@@ -0,0 +1,48 @@
+#include <iostream>
+#include <string>
+
+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 000000000000..8a7102e347af
--- /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 000000000000..fdc981ea178d
--- /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 000000000000..4f9ea3abf181
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/issue_11588/main.cpp
@@ -0,0 +1,54 @@
+//
+// 11588.cpp
+//
+
+#include <iostream>
+
+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 000000000000..01bb09a1b0d6
--- /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 000000000000..1ecd744be14b
--- /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 000000000000..c3d6306c5a63
--- /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 000000000000..e026bc018ace
--- /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 000000000000..cec6efbba990
--- /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 000000000000..f2c2c101fa15
--- /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 000000000000..81ae6f6f16ec
--- /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 000000000000..00c34820eef3
--- /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 000000000000..8a5a6a2b5416
--- /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 000000000000..ecd9a90f6626
--- /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 000000000000..8066198300fb
--- /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 000000000000..7b0707cdf22c
--- /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 000000000000..a2b6b703d6c8
--- /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 <assert.h>
+#import <Foundation/Foundation.h>
+#import <CloudKit/CloudKit.h>
+
+#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 000000000000..db5f575866d9
--- /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 000000000000..9d7359fb2d45
--- /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 000000000000..73346969eccc
--- /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 000000000000..0d70f2595019
--- /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 000000000000..3ea5b7040655
--- /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 000000000000..47c6675511fd
--- /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 000000000000..9e26e619bfdb
--- /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 000000000000..0d70f2595019
--- /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 000000000000..e148fcd89599
--- /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 000000000000..fd41471df8ed
--- /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 000000000000..4464e2ee9f5c
--- /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 000000000000..e415b92a43a6
--- /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 000000000000..3dbb024b2809
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/po_verbosity/main.m
@@ -0,0 +1,9 @@
+#import <Cocoa/Cocoa.h>
+
+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 000000000000..0d70f2595019
--- /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 000000000000..302b14b7360e
--- /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 000000000000..1329fd69a2e1
--- /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 <stdio.h>
+
+// 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 000000000000..0d70f2595019
--- /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 000000000000..fb16d2a93326
--- /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 000000000000..2bf05f2b3065
--- /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 <stdio.h>
+
+// 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 000000000000..0d70f2595019
--- /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 000000000000..ce3e51d05149
--- /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 000000000000..934abdfaef3e
--- /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 <stdio.h>
+
+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 000000000000..8a7102e347af
--- /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 000000000000..ec3e7f93af26
--- /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 <rdar://problem/14874559> 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 000000000000..578a037e9f0f
--- /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 000000000000..22208a87cb44
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/test/main.cpp
@@ -0,0 +1,44 @@
+#include <stdio.h>
+
+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: <rdar://problem/8686536>)
+ 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: <rdar://problem/8686536>)
+ expression printf("\"\n") // Test constant strings that contains an escaped double quote char (this is broken: <rdar://problem/8686536>)
+ expression printf("\'\n") // Test constant strings that contains an escaped single quote char (this is broken: <rdar://problem/8686536>)
+ 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 000000000000..c9cff412c1b2
--- /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 000000000000..a602afc47edb
--- /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 000000000000..ac37c5d243b2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/timeout/wait-a-while.cpp
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <stdint.h>
+
+#include <chrono>
+#include <thread>
+
+
+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 000000000000..5974461e256f
--- /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 000000000000..5b0233509112
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py
@@ -0,0 +1,39 @@
+"""
+Regression test for <rdar://problem/8981098>:
+
+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 000000000000..1609ebd838f6
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/two-files/foo.m
@@ -0,0 +1,28 @@
+#import <Foundation/Foundation.h>
+
+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 000000000000..3f5738314e6b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/expression_command/two-files/main.m
@@ -0,0 +1,22 @@
+#import <Foundation/Foundation.h>
+#include <stdio.h>
+
+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;
+}