diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/expression_command')
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 0000000000000..897e40a99dda0 --- /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 0000000000000..d4b82b3db2766 --- /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 0000000000000..3756b4a8cea48 --- /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 0000000000000..f6d63885248ab --- /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 0000000000000..9138af0b0b472 --- /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 0000000000000..9b494c712bcc0 --- /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 0000000000000..1c93ae1de439f --- /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 0000000000000..abf48742567df --- /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 0000000000000..f5c15b41e2de3 --- /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 0000000000000..ac07b31c48cc9 --- /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 0000000000000..0e766ac2953ae --- /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 0000000000000..a184718be7ddc --- /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 0000000000000..8a7102e347af2 --- /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 0000000000000..90e847fd5fa24 --- /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 0000000000000..c8b0beb1b3553 --- /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 0000000000000..8a7102e347af2 --- /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 0000000000000..0430fa55f995e --- /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 0000000000000..743b69434d5fe --- /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 0000000000000..8a7102e347af2 --- /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 0000000000000..3f47206480c37 --- /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 0000000000000..91c4d4a84c627 --- /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 0000000000000..ce922a8f911d2 --- /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 0000000000000..4c3b180f37098 --- /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 0000000000000..8a7102e347af2 --- /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 0000000000000..fdc981ea178d8 --- /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 0000000000000..4f9ea3abf181b --- /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 0000000000000..01bb09a1b0d6c --- /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 0000000000000..1ecd744be14b8 --- /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 0000000000000..c3d6306c5a630 --- /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 0000000000000..e026bc018acee --- /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 0000000000000..cec6efbba990e --- /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 0000000000000..f2c2c101fa15b --- /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 0000000000000..81ae6f6f16ec7 --- /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 0000000000000..00c34820eef36 --- /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 0000000000000..8a5a6a2b54160 --- /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 0000000000000..ecd9a90f6626b --- /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 0000000000000..8066198300fb2 --- /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 0000000000000..7b0707cdf22cc --- /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 0000000000000..a2b6b703d6c81 --- /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 0000000000000..db5f575866d94 --- /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 0000000000000..9d7359fb2d45b --- /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 0000000000000..73346969eccc4 --- /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 0000000000000..0d70f25950192 --- /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 0000000000000..3ea5b70406554 --- /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 0000000000000..47c6675511fd4 --- /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 0000000000000..9e26e619bfdb6 --- /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 0000000000000..0d70f25950192 --- /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 0000000000000..e148fcd89599c --- /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 0000000000000..fd41471df8edc --- /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 0000000000000..4464e2ee9f5cf --- /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 0000000000000..e415b92a43a62 --- /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 0000000000000..3dbb024b28096 --- /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 0000000000000..0d70f25950192 --- /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 0000000000000..302b14b7360eb --- /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 0000000000000..1329fd69a2e16 --- /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 0000000000000..0d70f25950192 --- /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 0000000000000..fb16d2a933265 --- /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 0000000000000..2bf05f2b30654 --- /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 0000000000000..0d70f25950192 --- /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 0000000000000..ce3e51d051498 --- /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 0000000000000..934abdfaef3e8 --- /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 0000000000000..8a7102e347af2 --- /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 0000000000000..ec3e7f93af26d --- /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 0000000000000..578a037e9f0f8 --- /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 0000000000000..22208a87cb446 --- /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 0000000000000..c9cff412c1b2d --- /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 0000000000000..a602afc47edb7 --- /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 0000000000000..ac37c5d243b29 --- /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 0000000000000..5974461e256f6 --- /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 0000000000000..5b0233509112a --- /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 0000000000000..1609ebd838f66 --- /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 0000000000000..3f5738314e6b1 --- /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; +}   | 
