diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/functionalities')
151 files changed, 2862 insertions, 740 deletions
diff --git a/packages/Python/lldbsuite/test/functionalities/asan/Makefile b/packages/Python/lldbsuite/test/functionalities/asan/Makefile index 26654a023ed1..dc8d682f831a 100644 --- a/packages/Python/lldbsuite/test/functionalities/asan/Makefile +++ b/packages/Python/lldbsuite/test/functionalities/asan/Makefile @@ -1,6 +1,6 @@  LEVEL = ../../make  C_SOURCES := main.c -CFLAGS_EXTRAS := -fsanitize=address -g +CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info  include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py b/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py index d7c511021863..ca070fa97dfa 100644 --- a/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py +++ b/packages/Python/lldbsuite/test/functionalities/asan/TestReportData.py @@ -37,6 +37,7 @@ class AsanTestReportDataCase(TestBase):          self.line_free = line_number('main.c', '// free line')          self.line_breakpoint = line_number('main.c', '// break line')          self.line_crash = line_number('main.c', '// BOOM line') +        self.col_crash = 16      def asan_tests(self):          exe = self.getBuildArtifact("a.out") @@ -63,7 +64,7 @@ class AsanTestReportDataCase(TestBase):              lldb.eStopReasonInstrumentation)          self.expect("bt", "The backtrace should show the crashing line", -                    substrs=['main.c:%d' % self.line_crash]) +                    substrs=['main.c:%d:%d' % (self.line_crash, self.col_crash)])          self.expect(              "thread info -s", diff --git a/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py b/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py index ad87796766c3..754acade015a 100644 --- a/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py +++ b/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py @@ -21,7 +21,7 @@ class AttachResumeTestCase(TestBase):      @skipIfRemote      @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr19310') -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778") +    @skipIfWindows # llvm.org/pr24778, llvm.org/pr21753      def test_attach_continue_interrupt_detach(self):          """Test attach/continue/interrupt/detach"""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/Makefile new file mode 100644 index 000000000000..6c22351dc3b5 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -std=c99 -gcolumn-info + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py new file mode 100644 index 000000000000..07032cc0380c --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py @@ -0,0 +1,48 @@ +""" +Test setting a breakpoint by line and column. +""" + +from __future__ import print_function + + +import os +import time +import re +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BreakpointByLineAndColumnTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info +    @skipIf(compiler="gcc", compiler_version=['<', '7.1']) +    def testBreakpointByLineAndColumn(self): +        self.build() +        main_c = lldb.SBFileSpec("main.c") +        _, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self, +                                                              main_c, 20, 50) +        self.expect("fr v did_call", substrs='1') +        in_then = False +        for i in range(breakpoint.GetNumLocations()): +            b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry() +            self.assertEqual(b_loc.GetLine(), 20) +            in_then |= b_loc.GetColumn() == 50 +        self.assertTrue(in_then) + +    ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info +    @skipIf(compiler="gcc", compiler_version=['<', '7.1']) +    def testBreakpointByLine(self): +        self.build() +        main_c = lldb.SBFileSpec("main.c") +        _, _, _, breakpoint = lldbutil.run_to_line_breakpoint(self, main_c, 20) +        self.expect("fr v did_call", substrs='0') +        in_condition = False +        for i in range(breakpoint.GetNumLocations()): +            b_loc = breakpoint.GetLocationAtIndex(i).GetAddress().GetLineEntry() +            self.assertEqual(b_loc.GetLine(), 20) +            in_condition |= b_loc.GetColumn() < 30 +        self.assertTrue(in_condition) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/main.c new file mode 100644 index 000000000000..921bc382023f --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_by_line_and_column/main.c @@ -0,0 +1,23 @@ +//===-- 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 square(int x) +{ +  return x * x; +} + +int main (int argc, char const *argv[]) +{ +  int did_call = 0; + +  // Line 20.                                    v Column 50. +  if(square(argc+1) != 0) { did_call = 1; return square(argc); } +  //                                             ^ +  return square(0); +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py index 7a2dc61b1b69..8143fa96433f 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py @@ -25,7 +25,6 @@ class BreakpointCommandTestCase(TestBase):          self.build()          self.breakpoint_command_sequence() -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")      def test_script_parameters(self):          """Test a sequence of breakpoint command add, list, and delete."""          self.build() @@ -45,7 +44,6 @@ class BreakpointCommandTestCase(TestBase):          self.addTearDownHook(              lambda: self.runCmd("settings clear auto-confirm")) -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")      def test_delete_all_breakpoints(self):          """Test that deleting all breakpoints works."""          self.build() @@ -133,9 +131,9 @@ class BreakpointCommandTestCase(TestBase):              patterns=[                  "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" %                  self.line, -                "1.1: .+at main.c:%d, .+unresolved, hit count = 0" % +                "1.1: .+at main.c:%d:?[0-9]*, .+unresolved, hit count = 0" %                  self.line, -                "2.1: .+at main.c:%d, .+unresolved, hit count = 0" % +                "2.1: .+at main.c:%d:?[0-9]*, .+unresolved, hit count = 0" %                  self.line])          self.expect("breakpoint command list 1", "Breakpoint 1 command ok", diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py index eb4bac7e6e66..e3bf4c27f31e 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py @@ -18,12 +18,14 @@ class BreakpointIgnoreCountTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) +    @skipIfWindows # This test will hang on windows llvm.org/pr21753      def test_with_run_command(self):          """Exercise breakpoint ignore count with 'breakpoint set -i <count>'."""          self.build()          self.breakpoint_ignore_count()      @add_test_categories(['pyapi']) +    @skipIfWindows # This test will hang on windows llvm.org/pr21753      def test_with_python_api(self):          """Use Python APIs to set breakpoint ignore count."""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/TestMoveNearest.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/TestMoveNearest.py index 16d5bc75473c..b8281e9c85bd 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/TestMoveNearest.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/TestMoveNearest.py @@ -18,6 +18,8 @@ class TestMoveNearest(TestBase):          # Find the line number to break inside main().          self.line1 = line_number('foo.h', '// !BR1')          self.line2 = line_number('foo.h', '// !BR2') +        self.line_between = line_number('main.cpp', "// BR_Between") +        print("BR_Between found at", self.line_between)          self.line_main = line_number('main.cpp', '// !BR_main')      def test(self): @@ -61,3 +63,7 @@ class TestMoveNearest(TestBase):          # "return .."          lldbutil.run_break_set_by_file_and_line(self, 'main.cpp',                  self.line_main+2, extra_options="-m 1") + +        # Make sure we don't put move the breakpoint if it is set between two functions: +        lldbutil.run_break_set_by_file_and_line(self, 'main.cpp', +                self.line_between, extra_options="-m 1", num_expected_locations=0) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/main.cpp index c9295a5c7d3c..76a22a5420fe 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/main.cpp @@ -1,7 +1,7 @@  #include "foo.h"  int call_foo2() { return foo2(); } - +// BR_Between  int  main() // !BR_main  { diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/Makefile new file mode 100644 index 000000000000..7934cd5db427 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/Makefile @@ -0,0 +1,9 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +ifneq (,$(findstring icc,$(CC))) +    CFLAGS += -debug inline-debug-info +endif + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.py new file mode 100644 index 000000000000..cda15fee84b8 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/TestRequireHWBreakpoints.py @@ -0,0 +1,106 @@ +""" +Test require hardware breakpoints. +""" + +from __future__ import print_function + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BreakpointLocationsTestCase(TestBase): +    NO_DEBUG_INFO_TESTCASE = True +    mydir = TestBase.compute_mydir(__file__) + +    def test_breakpoint(self): +        """Test regular breakpoints when hardware breakpoints are required.""" +        self.build() +        exe = self.getBuildArtifact("a.out") +        target = self.dbg.CreateTarget(exe) + +        self.runCmd("settings set target.require-hardware-breakpoint true") + +        breakpoint = target.BreakpointCreateByLocation("main.c", 1) +        self.assertTrue(breakpoint.IsHardware()) + +    @skipIfWindows +    def test_step_range(self): +        """Test stepping when hardware breakpoints are required.""" +        self.build() + +        _, _, thread, _ = lldbutil.run_to_line_breakpoint( +            self, lldb.SBFileSpec("main.c"), 1) + +        self.runCmd("settings set target.require-hardware-breakpoint true") + +        # Ensure we fail in the interpreter. +        self.expect("thread step-in") +        self.expect("thread step-in", error=True) + +        # Ensure we fail when stepping through the API. +        error = lldb.SBError() +        thread.StepInto('', 4, error) +        self.assertTrue(error.Fail()) +        self.assertTrue("Could not create hardware breakpoint for thread plan" +                        in error.GetCString()) + +    @skipIfWindows +    def test_step_out(self): +        """Test stepping out when hardware breakpoints are required.""" +        self.build() + +        _, _, thread, _ = lldbutil.run_to_line_breakpoint( +            self, lldb.SBFileSpec("main.c"), 1) + +        self.runCmd("settings set target.require-hardware-breakpoint true") + +        # Ensure this fails in the command interpreter. +        self.expect("thread step-out", error=True) + +        # Ensure we fail when stepping through the API. +        error = lldb.SBError() +        thread.StepOut(error) +        self.assertTrue(error.Fail()) +        self.assertTrue("Could not create hardware breakpoint for thread plan" +                        in error.GetCString()) + +    @skipIfWindows +    def test_step_over(self): +        """Test stepping over when hardware breakpoints are required.""" +        self.build() + +        _, _, thread, _ = lldbutil.run_to_line_breakpoint( +            self, lldb.SBFileSpec("main.c"), 7) + +        self.runCmd("settings set target.require-hardware-breakpoint true") + +        # Step over doesn't fail immediately but fails later on. +        self.expect("thread step-over") +        self.expect( +            "process status", +            substrs=[ +                'step over failed', +                'Could not create hardware breakpoint for thread plan' +            ]) + +    @skipIfWindows +    def test_step_until(self): +        """Test stepping until when hardware breakpoints are required.""" +        self.build() + +        _, _, thread, _ = lldbutil.run_to_line_breakpoint( +            self, lldb.SBFileSpec("main.c"), 7) + +        self.runCmd("settings set target.require-hardware-breakpoint true") + +        self.expect("thread until 5", error=True) + +        # Ensure we fail when stepping through the API. +        error = thread.StepOverUntil(lldb.SBFrame(), lldb.SBFileSpec(), 5) +        self.assertTrue(error.Fail()) +        self.assertTrue("Could not create hardware breakpoint for thread plan" +                        in error.GetCString()) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/main.c new file mode 100644 index 000000000000..7d49a57d4c7b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/require_hw_breakpoints/main.c @@ -0,0 +1,9 @@ +int break_on_me() { +  int i = 10; +  i++; +  return i; +} + +int main() { +  return break_on_me(); +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile b/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile new file mode 100644 index 000000000000..6067ee45e984 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -std=c99 + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py new file mode 100644 index 000000000000..0eb9033e754b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py @@ -0,0 +1,199 @@ +""" +Test setting breakpoints using a scripted resolver +""" + +from __future__ import print_function + + +import os +import time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * + + +class TestScriptedResolver(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    NO_DEBUG_INFO_TESTCASE = True + +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528") +    def test_scripted_resolver(self): +        """Use a scripted resolver to set a by symbol name breakpoint""" +        self.build() +        self.do_test() + +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528") +    def test_search_depths(self): +        """ Make sure we are called at the right depths depending on what we return +            from __get_depth__""" +        self.build() +        self.do_test_depths() + +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528") +    def test_command_line(self): +        """ Make sure we are called at the right depths depending on what we return +            from __get_depth__""" +        self.build() +        self.do_test_cli() + +    def setUp(self): +        # Call super's setUp(). +        TestBase.setUp(self) + +    def make_target_and_import(self): +        target = lldbutil.run_to_breakpoint_make_target(self) +        interp = self.dbg.GetCommandInterpreter() +        error = lldb.SBError() + +        script_name = os.path.join(self.getSourceDir(), "resolver.py") +        source_name = os.path.join(self.getSourceDir(), "main.c") + +        command = "command script import " + script_name +        result = lldb.SBCommandReturnObject() +        interp.HandleCommand(command, result) +        self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError())) +        return target + +    def make_extra_args(self): +        json_string = '{"symbol":"break_on_me", "test1": "value1"}' +        json_stream = lldb.SBStream() +        json_stream.Print(json_string) +        extra_args = lldb.SBStructuredData() +        error = extra_args.SetFromJSON(json_stream) +        self.assertTrue(error.Success(), "Error making SBStructuredData: %s"%(error.GetCString())) +        return extra_args + +    def do_test(self): +        """This reads in a python file and sets a breakpoint using it.""" + +        target = self.make_target_and_import() +        extra_args = self.make_extra_args() + +        file_list = lldb.SBFileSpecList() +        module_list = lldb.SBFileSpecList() + +        # Make breakpoints with this resolver using different filters, first ones that will take: +        right = [] +        # one with no file or module spec - this one should fire: +        right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + +        # one with the right source file and no module - should also fire: +        file_list.Append(lldb.SBFileSpec("main.c")) +        right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) +        # Make sure the help text shows up in the "break list" output: +        self.expect("break list", substrs=["I am a python breakpoint resolver"], msg="Help is listed in break list") + +        # one with the right source file and right module - should also fire: +        module_list.Append(lldb.SBFileSpec("a.out")) +        right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + +        # And one with no source file but the right module: +        file_list.Clear() +        right.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + +        # Make sure these all got locations: +        for i in range (0, len(right)): +            self.assertTrue(right[i].GetNumLocations() >= 1, "Breakpoint %d has no locations."%(i)) + +        # Now some ones that won't take: + +        module_list.Clear() +        file_list.Clear() +        wrong = [] + +        # one with the wrong module - should not fire: +        module_list.Append(lldb.SBFileSpec("noSuchModule")) +        wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) + +        # one with the wrong file - also should not fire: +        file_list.Clear() +        module_list.Clear() +        file_list.Append(lldb.SBFileSpec("noFileOfThisName.xxx")) +        wrong.append(target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list)) +         +        # Now make sure the CU level iteration obeys the file filters: +        file_list.Clear() +        module_list.Clear() +        file_list.Append(lldb.SBFileSpec("no_such_file.xxx")) +        wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)) + +        # And the Module filters: +        file_list.Clear() +        module_list.Clear() +        module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib")) +        wrong.append(target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list)) + +        # Now make sure the Function level iteration obeys the file filters: +        file_list.Clear() +        module_list.Clear() +        file_list.Append(lldb.SBFileSpec("no_such_file.xxx")) +        wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)) + +        # And the Module filters: +        file_list.Clear() +        module_list.Clear() +        module_list.Append(lldb.SBFileSpec("NoSuchModule.dylib")) +        wrong.append(target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list)) + +        # Make sure these didn't get locations: +        for i in range(0, len(wrong)): +            self.assertEqual(wrong[i].GetNumLocations(), 0, "Breakpoint %d has locations."%(i)) + +        # Now run to main and ensure we hit the breakpoints we should have: + +        lldbutil.run_to_breakpoint_do_run(self, target, right[0]) +         +        # Test the hit counts: +        for i in range(0, len(right)): +            self.assertEqual(right[i].GetHitCount(), 1, "Breakpoint %d has the wrong hit count"%(i)) + +        for i in range(0, len(wrong)): +            self.assertEqual(wrong[i].GetHitCount(), 0, "Breakpoint %d has the wrong hit count"%(i)) + +    def do_test_depths(self): +        """This test uses a class variable in resolver.Resolver which gets set to 1 if we saw +           compile unit and 2 if we only saw modules.  If the search depth is module, you get passed just +           the modules with no comp_unit.  If the depth is comp_unit you get comp_units.  So we can use +           this to test that our callback gets called at the right depth.""" + +        target = self.make_target_and_import() +        extra_args = self.make_extra_args() + +        file_list = lldb.SBFileSpecList() +        module_list = lldb.SBFileSpecList() +        module_list.Append(lldb.SBFileSpec("a.out")) + +        # Make a breakpoint that has no __get_depth__, check that that is converted to eSearchDepthModule: +        bkpt = target.BreakpointCreateFromScript("resolver.Resolver", extra_args, module_list, file_list) +        self.assertTrue(bkpt.GetNumLocations() > 0, "Resolver got no locations.") +        self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules") +         +        # Make a breakpoint that asks for modules, check that we didn't get any files: +        bkpt = target.BreakpointCreateFromScript("resolver.ResolverModuleDepth", extra_args, module_list, file_list) +        self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverModuleDepth got no locations.") +        self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules") +         +        # Make a breakpoint that asks for compile units, check that we didn't get any files: +        bkpt = target.BreakpointCreateFromScript("resolver.ResolverCUDepth", extra_args, module_list, file_list) +        self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverCUDepth got no locations.") +        self.expect("script print resolver.Resolver.got_files", substrs=["1"], msg="Was passed compile units") + +        # Make a breakpoint that returns a bad value - we should convert that to "modules" so check that: +        bkpt = target.BreakpointCreateFromScript("resolver.ResolverBadDepth", extra_args, module_list, file_list) +        self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverBadDepth got no locations.") +        self.expect("script print resolver.Resolver.got_files", substrs=["2"], msg="Was only passed modules") + +        # Make a breakpoint that searches at function depth: +        bkpt = target.BreakpointCreateFromScript("resolver.ResolverFuncDepth", extra_args, module_list, file_list) +        self.assertTrue(bkpt.GetNumLocations() > 0, "ResolverFuncDepth got no locations.") +        self.expect("script print resolver.Resolver.got_files", substrs=["3"], msg="Was only passed modules") +        self.expect("script print resolver.Resolver.func_list", substrs=["break_on_me", "main", "test_func"], msg="Saw all the functions") + +    def do_test_cli(self): +        target = self.make_target_and_import() + +        lldbutil.run_break_set_by_script(self, "resolver.Resolver", extra_options="-k symbol -v break_on_me") diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c b/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c new file mode 100644 index 000000000000..b91ccfc1b43e --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/main.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int +test_func() +{ +  return printf("I am a test function."); +} + +void +break_on_me() +{ +  printf("I was called.\n"); +} + +int +main() +{ +  break_on_me(); +  test_func(); +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py new file mode 100644 index 000000000000..61f5f2df20ac --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/scripted_bkpt/resolver.py @@ -0,0 +1,54 @@ +import lldb + +class Resolver: +  got_files = 0 +  func_list = [] + +  def __init__(self, bkpt, extra_args, dict): +      self.bkpt = bkpt +      self.extra_args = extra_args +      Resolver.func_list = [] +      Resolver.got_files = 0 + +  def __callback__(self, sym_ctx): +      sym_name = "not_a_real_function_name" +      sym_item = self.extra_args.GetValueForKey("symbol") +      if sym_item.IsValid(): +          sym_name = sym_item.GetStringValue(1000) + +      if sym_ctx.compile_unit.IsValid(): +          Resolver.got_files = 1 +      else: +          Resolver.got_files = 2 +       +      if sym_ctx.function.IsValid(): +        Resolver.got_files = 3 +        func_name = sym_ctx.function.GetName() +        Resolver.func_list.append(func_name) +        if sym_name == func_name: +          self.bkpt.AddLocation(sym_ctx.function.GetStartAddress()) +        return + +      if sym_ctx.module.IsValid(): +          sym = sym_ctx.module.FindSymbol(sym_name, lldb.eSymbolTypeCode) +          if sym.IsValid(): +              self.bkpt.AddLocation(sym.GetStartAddress()) + +  def get_short_help(self): +      return "I am a python breakpoint resolver" + +class ResolverModuleDepth(Resolver): +    def __get_depth__ (self): +        return lldb.eSearchDepthModule + +class ResolverCUDepth(Resolver): +    def __get_depth__ (self): +        return lldb.eSearchDepthCompUnit + +class ResolverFuncDepth(Resolver): +    def __get_depth__ (self): +        return lldb.eSearchDepthFunction + +class ResolverBadDepth(Resolver): +    def __get_depth__ (self): +        return lldb.kLastSearchDepthKind + 1 diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py index c615278e8d48..943998a421be 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py @@ -180,7 +180,8 @@ class BreakpointSerialization(TestBase):          # actually have locations.          source_bps = lldb.SBBreakpointList(self.orig_target) -        bkpt = self.orig_target.BreakpointCreateByLocation("blubby.c", 666) +        bkpt = self.orig_target.BreakpointCreateByLocation( +            lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())          bkpt.SetEnabled(False)          bkpt.SetOneShot(True)          bkpt.SetThreadID(10) @@ -226,7 +227,8 @@ class BreakpointSerialization(TestBase):          all_bps = lldb.SBBreakpointList(self.orig_target)          source_bps = lldb.SBBreakpointList(self.orig_target) -        bkpt = self.orig_target.BreakpointCreateByLocation("blubby.c", 666) +        bkpt = self.orig_target.BreakpointCreateByLocation( +            lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())          bkpt.SetEnabled(False)          bkpt.SetOneShot(True)          bkpt.SetThreadID(10) @@ -260,7 +262,8 @@ class BreakpointSerialization(TestBase):          self.check_equivalence(all_bps)      def do_check_names(self): -        bkpt = self.orig_target.BreakpointCreateByLocation("blubby.c", 666) +        bkpt = self.orig_target.BreakpointCreateByLocation( +            lldb.SBFileSpec("blubby.c"), 666, 333, 0, lldb.SBFileSpecList())          good_bkpt_name = "GoodBreakpoint"          write_bps = lldb.SBBreakpointList(self.orig_target)          bkpt.AddName(good_bkpt_name) diff --git a/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py b/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py index c6ad75f014ee..c1595cf25515 100644 --- a/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py +++ b/packages/Python/lldbsuite/test/functionalities/command_script_immediate_output/TestCommandScriptImmediateOutput.py @@ -28,6 +28,7 @@ class CommandScriptImmediateOutputTestCase (PExpectTest):          oslist=["windows"],          bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")      @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr26139") +    @skipIfDarwin      def test_command_script_immediate_output_console(self):          """Test that LLDB correctly allows scripted commands to set immediate output to the console."""          self.launch(timeout=10) @@ -50,6 +51,7 @@ class CommandScriptImmediateOutputTestCase (PExpectTest):          oslist=["windows"],          bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")      @expectedFailureAll(oslist=["freebsd"], bugnumber="llvm.org/pr26139") +    @skipIfDarwin      def test_command_script_immediate_output_file(self):          """Test that LLDB correctly allows scripted commands to set immediate output to a file."""          self.launch(timeout=10) diff --git a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py index 5d4fcf64511b..c073425a93fb 100644 --- a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py +++ b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py @@ -43,7 +43,6 @@ class CommandLineCompletionTestCase(TestBase):          self.build()          self.main_source = "main.cpp"          self.main_source_spec = lldb.SBFileSpec(self.main_source) -        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))          (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,                                            '// Break here', self.main_source_spec) @@ -177,8 +176,8 @@ class CommandLineCompletionTestCase(TestBase):      @skipIfFreeBSD  # timing out on the FreeBSD buildbot      def test_settings_s_dash(self): -        """Test that 'settings set -' completes to 'settings set -g'.""" -        self.complete_from_to('settings set -', 'settings set -g') +        """Test that 'settings set --g' completes to 'settings set --global'.""" +        self.complete_from_to('settings set --g', 'settings set --global')      @skipIfFreeBSD  # timing out on the FreeBSD buildbot      def test_settings_clear_th(self): @@ -275,6 +274,22 @@ class CommandLineCompletionTestCase(TestBase):          self.complete_from_to("watchpoint set variable foo --watch w", "watchpoint set variable foo --watch write")          self.complete_from_to('watchpoint set variable foo -w read_', 'watchpoint set variable foo -w read_write') +    def test_completion_description_commands(self): +        """Test descriptions of top-level command completions""" +        self.check_completion_with_desc("", [ +            ["command", "Commands for managing custom LLDB commands."], +            ["bugreport", "Commands for creating domain-specific bug reports."] +        ]) + +        self.check_completion_with_desc("pl", [ +            ["platform", "Commands to manage and create platforms."], +            ["plugin", "Commands for managing LLDB plugins."] +        ]) + +        # Just check that this doesn't crash. +        self.check_completion_with_desc("comman", []) +        self.check_completion_with_desc("non-existent-command", []) +      @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489")      def test_symbol_name(self):          self.build() @@ -282,39 +297,3 @@ class CommandLineCompletionTestCase(TestBase):          self.complete_from_to('breakpoint set -n Fo',                                'breakpoint set -n Foo::Bar(int,\\ int)',                                turn_off_re_match=True) - -    def complete_from_to(self, str_input, patterns, turn_off_re_match=False): -        """Test that the completion mechanism completes str_input to patterns, -        where patterns could be a pattern-string or a list of pattern-strings""" -        # Patterns should not be None in order to proceed. -        self.assertFalse(patterns is None) -        # And should be either a string or list of strings.  Check for list type -        # below, if not, make a list out of the singleton string.  If patterns -        # is not a string or not a list of strings, there'll be runtime errors -        # later on. -        if not isinstance(patterns, list): -            patterns = [patterns] - -        interp = self.dbg.GetCommandInterpreter() -        match_strings = lldb.SBStringList() -        num_matches = interp.HandleCompletion(str_input, len(str_input), 0, -1, match_strings) -        common_match = match_strings.GetStringAtIndex(0) -        if num_matches == 0: -            compare_string = str_input -        else: -            if common_match != None and len(common_match) > 0: -                compare_string = str_input + common_match -            else: -                compare_string = "" -                for idx in range(1, num_matches+1): -                    compare_string += match_strings.GetStringAtIndex(idx) + "\n" - -        for p in patterns: -            if turn_off_re_match: -                self.expect( -                    compare_string, msg=COMPLETION_MSG( -                        str_input, p, match_strings), exe=False, substrs=[p]) -            else: -                self.expect( -                    compare_string, msg=COMPLETION_MSG( -                        str_input, p, match_strings), exe=False, patterns=[p]) diff --git a/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py b/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py index 904fb4c90372..7b123950c23d 100644 --- a/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py +++ b/packages/Python/lldbsuite/test/functionalities/conditional_break/TestConditionalBreak.py @@ -34,9 +34,6 @@ class ConditionalBreakTestCase(TestBase):          self.build()          self.simulate_conditional_break_by_user() -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr26265: args in frames other than #0 are not evaluated correctly")      def do_conditional_break(self):          """Exercise some thread and frame APIs to break if c() is called by a()."""          exe = self.getBuildArtifact("a.out") diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py index 9749061f42d5..4b9de961724b 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py @@ -23,9 +23,6 @@ class CppDataFormatterTestCase(TestBase):          # Find the line number to break at.          self.line = line_number('main.cpp', '// Set break point at this line.') -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24462: Data formatters have problems on Windows")      @skipIf(debug_info="gmodules",              bugnumber="https://bugs.llvm.org/show_bug.cgi?id=36048")      def test_with_run_command(self): diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/main.cpp index aaccb6329acf..1c98f3db24c8 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-script/main.cpp @@ -50,4 +50,4 @@ int main (int argc, const char * argv[])      int dummy = 1;      return 0; -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp index 82ffb2c20d47..665c9fe75d1c 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp @@ -54,4 +54,4 @@ int main()      DeepData_2 data2;      return 0; // Set break point at this line. -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py index 13b38cbfa702..54e9c346df31 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py @@ -17,9 +17,6 @@ class SmartArrayDataFormatterTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24462, Data formatters have problems on Windows")      def test_with_run_command(self):          """Test data formatter commands."""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/function/TestLibCxxFunction.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/function/TestLibCxxFunction.py index 81a76cc65d63..e44ea61d120f 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/function/TestLibCxxFunction.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/function/TestLibCxxFunction.py @@ -40,13 +40,17 @@ class LibCxxFunctionTestCase(TestBase):                      substrs=['stopped',                               'stop reason = breakpoint']) -        f1 = self.get_variable('f1') -        f2 = self.get_variable('f2') +        self.expect("frame variable f1", +                    substrs=['f1 =  Function = foo(int, int)']) -        if self.TraceOn(): -            print(f1) -        if self.TraceOn(): -            print(f2) +        self.expect("frame variable f2", +                    substrs=['f2 =  Lambda in File main.cpp at Line 27']) -        self.assertTrue(f1.GetValueAsUnsigned(0) != 0, 'f1 has a valid value') -        self.assertTrue(f2.GetValueAsUnsigned(0) != 0, 'f2 has a valid value') +        self.expect("frame variable f3", +                    substrs=['f3 =  Lambda in File main.cpp at Line 31']) + +        self.expect("frame variable f4", +                    substrs=['f4 =  Function in File main.cpp at Line 17']) + +        self.expect("frame variable f5", +                    substrs=['f5 =  Function = Bar::add_num(int) const']) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/function/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/function/main.cpp index cfe689b29b01..541fdaca2afa 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/function/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/function/main.cpp @@ -13,13 +13,28 @@ int foo(int x, int y) {    return x + y - 1;  } -int main () +struct Bar { +   int operator()() { +       return 66 ; +   } +   int add_num(int i) const { return i + 3 ; } +} ; + +int main (int argc, char *argv[])  {    int acc = 42;    std::function<int (int,int)> f1 = foo;    std::function<int (int)> f2 = [acc,f1] (int x) -> int {      return x+f1(acc,x);    }; -    return f1(acc,acc) + f2(acc); // Set break point at this line. -} +  auto f = [](int x, int y) { return x + y; }; +  auto g = [](int x, int y) { return x * y; } ; +  std::function<int (int,int)> f3 =  argc %2 ? f : g ; + +  Bar bar1 ; +  std::function<int ()> f4( bar1 ) ; +  std::function<int (const Bar&, int)> f5 = &Bar::add_num; + +  return f1(acc,acc) + f2(acc) + f3(acc+1,acc+2) + f4() + f5(bar1, 10); // Set break point at this line. +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py index 90a7e119fb84..86248d1cac24 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py @@ -190,6 +190,7 @@ class LibcxxListDataFormatterTestCase(TestBase):          self.runCmd("n") # This gets us past the printf          self.runCmd("n") +        self.runCmd("n")          # check access-by-index          self.expect("frame variable text_list[0]", diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp index 6247ca8b2412..da6eca985d20 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/main.cpp @@ -74,4 +74,4 @@ int main()      ss.clear();      thefoo_rw(1);  // Set break point at this line.          return 0; -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp index e8385994125d..27bdc0a57729 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multimap/main.cpp @@ -74,4 +74,4 @@ int main()      ss.clear();      thefoo_rw(1);  // Set break point at this line.          return 0; -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile new file mode 100644 index 000000000000..19d6fc3e3c25 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../../../make + +CXX_SOURCES := main.cpp + +USE_LIBCPP := 1 +include $(LEVEL)/Makefile.rules +CXXFLAGS += -std=c++17 -fno-exceptions diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py new file mode 100644 index 000000000000..7826305931da --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py @@ -0,0 +1,75 @@ +""" +Test lldb data formatter subsystem. +""" + +from __future__ import print_function + + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LibcxxOptionalDataFormatterTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    @add_test_categories(["libc++"]) +    ## We are skipping clang version less that 5.0 since this test requires -std=c++17 +    @skipIf(oslist=no_match(["macosx"]), compiler="clang", compiler_version=['<', '5.0']) +    ## We are skipping gcc version less that 5.1 since this test requires -std=c++17 +    @skipIf(compiler="gcc", compiler_version=['<', '5.1']) + +    def test_with_run_command(self): +        """Test that that file and class static variables display correctly.""" +        self.build() +        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + +        bkpt = self.target().FindBreakpointByID( +            lldbutil.run_break_set_by_source_regexp( +                self, "break here")) + +        self.runCmd("run", RUN_SUCCEEDED) + +        # The stop reason of the thread should be breakpoint. +        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, +                    substrs=['stopped', +                             'stop reason = breakpoint']) + +        self.runCmd( "frame variable has_optional" ) + +        output = self.res.GetOutput() + +        ## The variable has_optional tells us if the test program +        ## detected we have a sufficient libc++ version to support optional +        ## false means we do not and therefore should skip the test +        if output.find("(bool) has_optional = false") != -1 : +           self.skipTest( "Optional not supported" )  + +        lldbutil.continue_to_breakpoint(self.process(), bkpt) + +        self.expect("frame variable number_not_engaged", +                    substrs=['Has Value=false']) + +        self.expect("frame variable number_engaged", +                    substrs=['Has Value=true', +                             'Value = 42', +                             '}']) + +        self.expect("frame var numbers", +                    substrs=['(optional_int_vect) numbers =  Has Value=true  {', +                             'Value = size=4 {', +                               '[0] = 1', +                               '[1] = 2', +                               '[2] = 3', +                               '[3] = 4', +                               '}', +                             '}']) + +        self.expect("frame var ostring", +                    substrs=['(optional_string) ostring =  Has Value=true  {', +                        'Value = "hello"', +                        '}']) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp new file mode 100644 index 000000000000..16bb98c61056 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp @@ -0,0 +1,42 @@ +#include <cstdio> +#include <string> +#include <vector> + +// If we have libc++ 4.0 or greater we should have <optional> +// According to libc++ C++1z status page https://libcxx.llvm.org/cxx1z_status.html +#if _LIBCPP_VERSION >= 4000 +#include <optional> +#define HAVE_OPTIONAL 1 +#else +#define HAVE_OPTIONAL 0 +#endif + + +int main() +{ +    bool has_optional = HAVE_OPTIONAL ; + +    printf( "%d\n", has_optional ) ; // break here + +#if HAVE_OPTIONAL == 1 +    using int_vect = std::vector<int> ; +    using optional_int = std::optional<int> ; +    using optional_int_vect = std::optional<int_vect> ; +    using optional_string = std::optional<std::string> ; + +    optional_int number_not_engaged ; +    optional_int number_engaged = 42 ; + +    printf( "%d\n", *number_engaged) ; + +    optional_int_vect numbers{{1,2,3,4}} ; + +    printf( "%d %d\n", numbers.value()[0], numbers.value()[1] ) ; + +    optional_string ostring = "hello" ; + +    printf( "%s\n", ostring->c_str() ) ; +#endif + +    return 0; // break here +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile index 1f609a41d908..937b47ea06b0 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile @@ -4,4 +4,4 @@ CXX_SOURCES := main.cpp  USE_LIBCPP := 1  include $(LEVEL)/Makefile.rules -CXXFLAGS += -O0 +CXXFLAGS += -std=c++11 -O0 diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py index 4574a044488c..63164f78e00e 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py @@ -68,7 +68,9 @@ class LibcxxStringDataFormatterTestCase(TestBase):                  '(%s::string) q = "hello world"'%ns,                  '(%s::string) Q = "quite a long std::strin with lots of info inside it"'%ns,                  '(%s::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"'%ns, -                '(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'%ns]) +                '(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'%ns, +                '(%s::u16string) u16_string = u"ß水氶"'%ns, +                '(%s::u32string) u32_string = U"🍄🍅🍆🍌"'%ns])          self.runCmd("n") @@ -98,4 +100,6 @@ class LibcxxStringDataFormatterTestCase(TestBase):                  '(%s::string) q = "hello world"'%ns,                  '(%s::string) Q = "quite a long std::strin with lots of info inside it"'%ns,                  '(%s::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"'%ns, -                '(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'%ns]) +                '(%s::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'%ns, +                '(%s::u16string) u16_string = u"ß水氶"'%ns, +                '(%s::u32string) u32_string = U"🍄🍅🍆🍌"'%ns]) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp index 9ca0da39cfc8..838a4c71be1a 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp @@ -10,6 +10,8 @@ int main()      std::string TheVeryLongOne("1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890someText1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");      std::string IHaveEmbeddedZeros("a\0b\0c\0d",7);      std::wstring IHaveEmbeddedZerosToo(L"hello world!\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監", 38); +    std::u16string u16_string(u"ß水氶"); +    std::u32string u32_string(U"🍄🍅🍆🍌");      S.assign(L"!!!!!"); // Set break point at this line.      return 0;  } diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/Makefile new file mode 100644 index 000000000000..a6ea665ef63c --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../../../make + +CXX_SOURCES := main.cpp + +USE_LIBCPP := 1 +include $(LEVEL)/Makefile.rules +CXXFLAGS += -std=c++17 diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py new file mode 100644 index 000000000000..e1f6961b465d --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/TestDataFormatterLibcxxVariant.py @@ -0,0 +1,83 @@ +""" +Test lldb data formatter subsystem. +""" + +from __future__ import print_function + + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class LibcxxVariantDataFormatterTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    @add_test_categories(["libc++"]) +    ## We are skipping clang version less that 5.0 since this test requires -std=c++17 +    @skipIf(oslist=no_match(["macosx"]), compiler="clang", compiler_version=['<', '5.0']) +    ## We are skipping gcc version less that 5.1 since this test requires -std=c++17 +    @skipIf(compiler="gcc", compiler_version=['<', '5.1']) +    ## std::get is unavailable for std::variant before macOS 10.14 +    @skipIf(macos_version=["<", "10.14"]) + +    def test_with_run_command(self): +        """Test that that file and class static variables display correctly.""" +        self.build() + +        (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here', +                lldb.SBFileSpec("main.cpp", False)) + +        self.runCmd( "frame variable has_variant" ) + +        output = self.res.GetOutput() + +        ## The variable has_variant tells us if the test program +        ## detected we have a sufficient libc++ version to support variant +        ## false means we do not and therefore should skip the test +        if output.find("(bool) has_variant = false") != -1 : +            self.skipTest( "std::variant not supported" ) + +        lldbutil.continue_to_breakpoint(self.process, bkpt) + +        self.expect("frame variable v1", +                substrs=['v1 =  Active Type = int  {', +                               'Value = 12', +                               '}']) + +        self.expect("frame variable v1_ref", +                substrs=['v1_ref =  Active Type = int : {', +                               'Value = 12', +                               '}']) + +        self.expect("frame variable v_v1", +                substrs=['v_v1 =  Active Type = std::__1::variant<int, double, char>  {', +                                 'Value =  Active Type = int  {', +                                   'Value = 12', +                                 '}', +                               '}']) + +        lldbutil.continue_to_breakpoint(self.process, bkpt) + +        self.expect("frame variable v1", +                substrs=['v1 =  Active Type = double  {', +                               'Value = 2', +                               '}']) + +        lldbutil.continue_to_breakpoint(self.process, bkpt) + +        self.expect("frame variable v2", +                substrs=['v2 =  Active Type = double  {', +                               'Value = 2', +                               '}']) + +        self.expect("frame variable v3", +                substrs=['v3 =  Active Type = char  {', +                               'Value = \'A\'', +                               '}']) + +        self.expect("frame variable v_no_value", +                    substrs=['v_no_value =  No Value']) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/main.cpp new file mode 100644 index 000000000000..c0bc4ae12c1a --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/variant/main.cpp @@ -0,0 +1,60 @@ +#include <cstdio> +#include <string> +#include <vector> + +// If we have libc++ 4.0 or greater we should have <variant> +// According to libc++ C++1z status page https://libcxx.llvm.org/cxx1z_status.html +#if _LIBCPP_VERSION >= 4000 +#include <variant> +#define HAVE_VARIANT 1 +#else +#define HAVE_VARIANT 0 +#endif + +struct S { +  operator int() { throw 42; } +} ; + + +int main() +{ +    bool has_variant = HAVE_VARIANT ; + +    printf( "%d\n", has_variant ) ; // break here + +#if HAVE_VARIANT == 1 +    std::variant<int, double, char> v1; +    std::variant<int, double, char> &v1_ref = v1; +    std::variant<int, double, char> v2; +    std::variant<int, double, char> v3; +    std::variant<std::variant<int,double,char>> v_v1 ; +    std::variant<int, double, char> v_no_value; + +    v1 = 12; // v contains int +    v_v1 = v1 ; +    int i = std::get<int>(v1); +    printf( "%d\n", i ); // break here + +    v2 = 2.0 ; +    double d = std::get<double>(v2) ; +    printf( "%f\n", d ); + +    v3 = 'A' ; +    char c = std::get<char>(v3) ; +    printf( "%d\n", c ); + +    // Checking v1 above and here to make sure we done maintain the incorrect +    // state when we change its value. +    v1 = 2.0; +    d = std::get<double>(v1) ; +    printf( "%f\n", d ); // break here + +     try { +       v_no_value.emplace<0>(S()); +     } catch( ... ) {} + +     printf( "%zu\n", v_no_value.index() ) ; +#endif + +    return 0; // break here +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py index 237e27fe1f31..06d3cda61be2 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py @@ -51,8 +51,6 @@ class LibcxxVectorDataFormatterTestCase(TestBase):                      substrs=['1234'])      @add_test_categories(["libc++"]) -    @skipIf(debug_info="gmodules", -            bugnumber="https://bugs.llvm.org/show_bug.cgi?id=36048")      def test_with_run_command(self):          """Test that that file and class static variables display correctly."""          self.build() @@ -180,8 +178,6 @@ class LibcxxVectorDataFormatterTestCase(TestBase):                      substrs=['vector has 0 items'])      @add_test_categories(["libc++"]) -    @skipIf(debug_info="gmodules", -            bugnumber="https://bugs.llvm.org/show_bug.cgi?id=36048")      def test_ref_and_ptr(self):          """Test that that file and class static variables display correctly."""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp index d7b046c5bff8..7ddffd19012e 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp @@ -35,4 +35,4 @@ int main()  	svter svI = sv.begin();      return 0; // Set break point at this line. -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp index 568c35efe072..d5e5b212782d 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/main.cpp @@ -52,4 +52,4 @@ int main()      ss.clear();// Set break point at this line.      return 0;// Set break point at this line. -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp index 4a9b4fc7d0db..f6e56cf12456 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp @@ -9,4 +9,4 @@ int main()      std::string Q("quite a long std::strin with lots of info inside it");      S.assign(L"!!!!!"); // Set break point at this line.      return 0; -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py index 5d05418a8b49..f782a2a8baea 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py @@ -66,6 +66,7 @@ class StdUniquePtrDataFormatterTestCase(TestBase):      @skipIfWindows  # libstdcpp not ported to Windows      @skipIfDarwin  # doesn't compile on Darwin      @skipIfwatchOS  # libstdcpp not ported to watchos +    @add_test_categories(["libstdcxx"])      def test_recursive_unique_ptr(self):          # Tests that LLDB can handle when we have a loop in the unique_ptr          # reference chain and that it correctly handles the different options diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py index 08768a61bd9d..138b32802951 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-synthval/TestDataFormatterSynthVal.py @@ -24,9 +24,6 @@ class DataFormatterSynthValueTestCase(TestBase):          self.line = line_number('main.cpp', 'break here')      @skipIfFreeBSD  # llvm.org/pr20545 bogus output confuses buildbot parser -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24462, Data formatters have problems on Windows")      def test_with_run_command(self):          """Test using Python synthetic children provider to provide a value."""          self.build() @@ -107,7 +104,7 @@ class DataFormatterSynthValueTestCase(TestBase):          # check that an aptly defined synthetic provider does not affect          # one-lining          self.expect( -            "expression struct S { myInt theInt{12}; }; S()", +            "expression struct Struct { myInt theInt{12}; }; Struct()",              substrs=['(theInt = 12)'])          # check that we can use a synthetic value in a summary diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp index fec7907e0031..90571b59f81e 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/synthcapping/main.cpp @@ -59,4 +59,4 @@ int main()                 256*256*256*'D');      return 0; -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/main.cpp index 649c1e09a6a5..5b43102c268c 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/typedef_array/main.cpp @@ -9,6 +9,11 @@  typedef int Foo;  int main() { +    // CHECK: (Foo [3]) array = { +    // CHECK-NEXT: (Foo) [0] = 1 +    // CHECK-NEXT: (Foo) [1] = 2 +    // CHECK-NEXT: (Foo) [2] = 3 +    // CHECK-NEXT: }      Foo array[3] = {1,2,3}; -    return 0; //% self.expect("frame variable array --show-types --", substrs = ['(Foo [3]) array = {','(Foo) [0] = 1','(Foo) [1] = 2','(Foo) [2] = 3']) +    return 0; //% self.filecheck("frame variable array --show-types --", 'main.cpp')  } diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py index d3c04afe91eb..670edad37f9e 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py @@ -14,7 +14,7 @@ from lldbsuite.test.lldbtest import *  from lldbsuite.test import lldbutil -class PythonSynthDataFormatterTestCase(TestBase): +class DataFormatterVarScriptFormatting(TestBase):      mydir = TestBase.compute_mydir(__file__) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/main.cpp index 4dc94af3566c..e9a36f911964 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/varscript_formatting/main.cpp @@ -5,4 +5,4 @@ int main() {      something<int> x;      something<void*> y;      return 0; // Set breakpoint here. -}
\ No newline at end of file +} diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/Makefile b/packages/Python/lldbsuite/test/functionalities/deleted-executable/Makefile index 8a7102e347af..8a7102e347af 100644 --- a/packages/Python/lldbsuite/test/functionalities/stop-hook/Makefile +++ b/packages/Python/lldbsuite/test/functionalities/deleted-executable/Makefile diff --git a/packages/Python/lldbsuite/test/functionalities/deleted-executable/TestDeletedExecutable.py b/packages/Python/lldbsuite/test/functionalities/deleted-executable/TestDeletedExecutable.py new file mode 100644 index 000000000000..1eeaeeffa87b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/deleted-executable/TestDeletedExecutable.py @@ -0,0 +1,31 @@ +""" +Test process attach/resume. +""" + +from __future__ import print_function + + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestDeletedExecutable(TestBase): + +    mydir = TestBase.compute_mydir(__file__) +    NO_DEBUG_INFO_TESTCASE = True + +    @skipIfWindows # cannot delete a running executable +    @expectedFailureAll(oslist=["linux"]) # determining the architecture of the process fails +    def test(self): +        self.build() +        exe = self.getBuildArtifact("a.out") + +        popen = self.spawnSubprocess(exe) +        self.addTearDownHook(self.cleanupSubprocesses) +        os.remove(exe) + +        self.runCmd("process attach -p " + str(popen.pid)) +        self.runCmd("kill") diff --git a/packages/Python/lldbsuite/test/functionalities/deleted-executable/main.cpp b/packages/Python/lldbsuite/test/functionalities/deleted-executable/main.cpp new file mode 100644 index 000000000000..ad5d18732eac --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/deleted-executable/main.cpp @@ -0,0 +1,9 @@ +#include <chrono> +#include <thread> + +int main(int argc, char const *argv[]) +{ +    lldb_enable_attach(); + +    std::this_thread::sleep_for(std::chrono::seconds(30)); +} diff --git a/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py index 52f9daf6bd45..91b858b4665a 100644 --- a/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py +++ b/packages/Python/lldbsuite/test/functionalities/disassembly/TestDisassembleBreakpoint.py @@ -18,9 +18,6 @@ class DisassemblyTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__)      NO_DEBUG_INFO_TESTCASE = True -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="function names print fully demangled instead of name-only")      def test(self):          self.build()          target, _, _, bkpt = lldbutil.run_to_source_breakpoint(self, diff --git a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py deleted file mode 100644 index 0f130b3ecbab..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/TestConvenienceVariables.py +++ /dev/null @@ -1,108 +0,0 @@ -"""Test convenience variables when you drop in from lldb prompt into an embedded interpreter.""" - -from __future__ import print_function - - -import os -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class ConvenienceVariablesCase(TestBase): - -    mydir = TestBase.compute_mydir(__file__) - -    def setUp(self): -        # Call super's setUp(). -        TestBase.setUp(self) -        # Find the line number to break on inside main.cpp. -        self.line = line_number('main.c', 'Hello world.') - -    @skipIfFreeBSD  # llvm.org/pr17228 -    @skipIfRemote -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr22274: need a pexpect replacement for windows") -    def test_with_run_commands(self): -        """Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame.""" -        self.build() -        import pexpect -        exe = self.getBuildArtifact("a.out") -        prompt = "(lldb) " -        python_prompt = ">>> " - -        # So that the child gets torn down after the test. -        self.child = pexpect.spawn( -            '%s %s %s' % -            (lldbtest_config.lldbExec, self.lldbOption, exe)) -        child = self.child -        # Turn on logging for what the child sends back. -        if self.TraceOn(): -            child.logfile_read = sys.stdout - -        # Set the breakpoint, run the inferior, when it breaks, issue print on -        # the various convenience variables. -        child.expect_exact(prompt) -        child.sendline('breakpoint set -f main.c -l %d' % self.line) -        child.expect_exact(prompt) -        child.sendline('run') -        child.expect_exact("stop reason = breakpoint 1.1") -        child.expect_exact(prompt) -        child.sendline('script') -        child.expect_exact(python_prompt) - -        # Set a flag so that we know during teardown time, we need to exit the -        # Python interpreter, then the lldb interpreter. -        self.child_in_script_interpreter = True - -        child.sendline('print(lldb.debugger)') -        child.expect_exact(python_prompt) -        self.expect(child.before, exe=False, -                    patterns=['Debugger \(instance: .*, id: \d\)']) - -        child.sendline('print(lldb.target)') -        child.expect_exact(python_prompt) -        self.expect(child.before, exe=False, -                    substrs=['a.out']) - -        child.sendline('print(lldb.process)') -        child.expect_exact(python_prompt) -        self.expect(child.before, exe=False, patterns=[ -                    'SBProcess: pid = \d+, state = stopped, threads = \d, executable = a.out']) - -        child.sendline('print(lldb.thread.GetStopDescription(100))') -        child.expect_exact(python_prompt) -        self.expect( -            child.before, -            exe=False, -            patterns=[ -                'breakpoint 1\.1']) - -        child.sendline('lldb.frame.GetLineEntry().GetLine()') -        child.expect_exact(python_prompt) -        line_number = "%d"%(self.line) -        self.expect( -            child.before, -            exe=False, -            substrs=[ -                line_number]) - -        child.sendline('lldb.frame.GetLineEntry().GetFileSpec().GetFilename()') -        child.expect_exact(python_prompt) -        line_number = "%d"%(self.line) -        self.expect( -            child.before, -            exe=False, -            substrs=[ -                "main.c"]) - -        child.sendline('lldb.frame.GetFunctionName()') -        child.expect_exact(python_prompt) -        line_number = "%d"%(self.line) -        self.expect( -            child.before, -            exe=False, -            substrs=[ -                "main"]) diff --git a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/main.c b/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/main.c deleted file mode 100644 index 277aa54a4eea..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/main.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <stdio.h> - -int main(int argc, char const *argv[]) { -    printf("Hello world.\n"); -    return 0; -} diff --git a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py index 8126a7ec750c..2cec254acc0c 100644 --- a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py +++ b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py @@ -31,12 +31,14 @@ class ExecTestCase(TestBase):      @skipUnlessDarwin      @expectedFailureAll(archs=['i386'], bugnumber="rdar://28656532")      @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems +    @skipIfSanitized # rdar://problem/43756823      def test_hitting_exec (self):          self.do_test(False)      @skipUnlessDarwin      @expectedFailureAll(archs=['i386'], bugnumber="rdar://28656532")      @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems +    @skipIfSanitized # rdar://problem/43756823      def test_skipping_exec (self):          self.do_test(True) @@ -61,6 +63,8 @@ class ExecTestCase(TestBase):              None, None, self.get_process_working_directory())          self.assertTrue(process, PROCESS_IS_VALID) +        if self.TraceOn(): +            self.runCmd("settings show target.process.stop-on-exec", check=False)          if skip_exec:              self.dbg.HandleCommand("settings set target.process.stop-on-exec false")              def cleanup(): @@ -94,6 +98,8 @@ class ExecTestCase(TestBase):          process.Continue()          if not skip_exec: +            self.assertFalse(process.GetState() == lldb.eStateExited, +                             "Process should not have exited!")              self.assertTrue(process.GetState() == lldb.eStateStopped,                              "Process should be stopped at __dyld_start") diff --git a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/Makefile b/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile index 0d70f2595019..0d70f2595019 100644 --- a/packages/Python/lldbsuite/test/functionalities/embedded_interpreter/Makefile +++ b/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/Makefile diff --git a/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py b/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py new file mode 100644 index 000000000000..56abc19f4f30 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/TestExprEntryBP.py @@ -0,0 +1,34 @@ +""" +Tests expressions evaluation when the breakpoint on module's entry is set. +""" + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ExprEntryBPTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    NO_DEBUG_INFO_TESTCASE = True + +    def test_expr_entry_bp(self): +        """Tests expressions evaluation when the breakpoint on module's entry is set.""" +        self.build() +        self.main_source_file = lldb.SBFileSpec("main.c") + +        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) + +        self.assertEqual(1, bkpt.GetNumLocations()) +        entry = bkpt.GetLocationAtIndex(0).GetAddress().GetModule().GetObjectFileEntryPointAddress() +        self.assertTrue(entry.IsValid(), "Can't get a module entry point") + +        entry_bp = target.BreakpointCreateBySBAddress(entry) +        self.assertTrue(entry_bp.IsValid(), "Can't set a breakpoint on the module entry point") + +        result = target.EvaluateExpression("sum(7, 1)") +        self.assertTrue(result.IsValid(), "Can't evaluate expression") +        self.assertEqual(8, result.GetValueAsSigned()) + +    def setUp(self): +        TestBase.setUp(self) diff --git a/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c b/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c new file mode 100644 index 000000000000..168fc9c8ccbf --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/expr-entry-bp/main.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +int sum(int x, int y) { +  return x + y; +} + +int main() { +  printf("Set a breakpoint here.\n"); +  return sum(-1, 1); +} diff --git a/packages/Python/lldbsuite/test/functionalities/frame-recognizer/Makefile b/packages/Python/lldbsuite/test/functionalities/frame-recognizer/Makefile new file mode 100644 index 000000000000..45f00b3e9861 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/frame-recognizer/Makefile @@ -0,0 +1,10 @@ +LEVEL = ../../make + +OBJC_SOURCES := main.m + +CFLAGS_EXTRAS += -g0 # No debug info. +MAKE_DSYM := NO + +include $(LEVEL)/Makefile.rules + +LDFLAGS += -framework Foundation diff --git a/packages/Python/lldbsuite/test/functionalities/frame-recognizer/TestFrameRecognizer.py b/packages/Python/lldbsuite/test/functionalities/frame-recognizer/TestFrameRecognizer.py new file mode 100644 index 000000000000..1162157bad57 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/frame-recognizer/TestFrameRecognizer.py @@ -0,0 +1,117 @@ +# encoding: utf-8 +""" +Test lldb's frame recognizers. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +import recognizer + +class FrameRecognizerTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) +    NO_DEBUG_INFO_TESTCASE = True + +    @skipUnlessDarwin +    def test_frame_recognizer_1(self): +        self.build() + +        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) +        self.assertTrue(target, VALID_TARGET) + +        self.runCmd("command script import " + os.path.join(self.getSourceDir(), "recognizer.py")) + +        self.expect("frame recognizer list", +                    substrs=['no matching results found.']) + +        self.runCmd("frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo") + +        self.expect("frame recognizer list", +                    substrs=['0: recognizer.MyFrameRecognizer, module a.out, function foo']) + +        self.runCmd("frame recognizer add -l recognizer.MyOtherFrameRecognizer -s a.out -n bar -x") + +        self.expect("frame recognizer list", +                    substrs=['0: recognizer.MyFrameRecognizer, module a.out, function foo', +                             '1: recognizer.MyOtherFrameRecognizer, module a.out, function bar (regexp)' +                    ]) + +        self.runCmd("frame recognizer delete 0") + +        self.expect("frame recognizer list", +                    substrs=['1: recognizer.MyOtherFrameRecognizer, module a.out, function bar (regexp)']) + +        self.runCmd("frame recognizer clear") + +        self.expect("frame recognizer list", +                    substrs=['no matching results found.']) + +        self.runCmd("frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo") + +        lldbutil.run_break_set_by_symbol(self, "foo") +        self.runCmd("r") + +        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, +                    substrs=['stopped', 'stop reason = breakpoint']) + +        process = target.GetProcess() +        thread = process.GetSelectedThread() +        frame = thread.GetSelectedFrame() + +        self.assertEqual(frame.GetSymbol().GetName(), "foo") +        self.assertFalse(frame.GetLineEntry().IsValid()) + +        self.expect("frame variable", +                    substrs=['(int) a = 42', '(int) b = 56']) + +        # Recognized arguments don't show up by default... +        variables = frame.GetVariables(lldb.SBVariablesOptions()) +        self.assertEqual(variables.GetSize(), 0) + +        # ...unless you set target.display-recognized-arguments to 1... +        self.runCmd("settings set target.display-recognized-arguments 1") +        variables = frame.GetVariables(lldb.SBVariablesOptions()) +        self.assertEqual(variables.GetSize(), 2) + +        # ...and you can reset it back to 0 to hide them again... +        self.runCmd("settings set target.display-recognized-arguments 0") +        variables = frame.GetVariables(lldb.SBVariablesOptions()) +        self.assertEqual(variables.GetSize(), 0) + +        # ... or explicitly ask for them with SetIncludeRecognizedArguments(True). +        opts = lldb.SBVariablesOptions() +        opts.SetIncludeRecognizedArguments(True) +        variables = frame.GetVariables(opts) + +        self.assertEqual(variables.GetSize(), 2) +        self.assertEqual(variables.GetValueAtIndex(0).name, "a") +        self.assertEqual(variables.GetValueAtIndex(0).signed, 42) +        self.assertEqual(variables.GetValueAtIndex(1).name, "b") +        self.assertEqual(variables.GetValueAtIndex(1).signed, 56) + +        self.expect("frame recognizer info 0", +                    substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer']) + +        self.expect("frame recognizer info 999", error=True, +                    substrs=['no frame with index 999']) + +        self.expect("frame recognizer info 1", +                    substrs=['frame 1 not recognized by any recognizer']) + +        # FIXME: The following doesn't work yet, but should be fixed. +        """ +        lldbutil.run_break_set_by_symbol(self, "bar") +        self.runCmd("c") + +        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, +                    substrs=['stopped', 'stop reason = breakpoint']) + +        self.expect("frame variable -t", +                    substrs=['(int *) a = ']) + +        self.expect("frame variable -t *a", +                    substrs=['*a = 78']) +        """ diff --git a/packages/Python/lldbsuite/test/functionalities/frame-recognizer/main.m b/packages/Python/lldbsuite/test/functionalities/frame-recognizer/main.m new file mode 100644 index 000000000000..51103ae038ac --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/frame-recognizer/main.m @@ -0,0 +1,28 @@ +//===-- main.m ------------------------------------------------*- ObjC -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +void foo(int a, int b) +{ +    printf("%d %d\n", a, b); +} + +void bar(int *ptr) +{ +	printf("%d\n", *ptr); +} + +int main (int argc, const char * argv[]) +{ +    foo(42, 56); +    int i = 78; +    bar(&i); +    return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/frame-recognizer/recognizer.py b/packages/Python/lldbsuite/test/functionalities/frame-recognizer/recognizer.py new file mode 100644 index 000000000000..a8a506745118 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/frame-recognizer/recognizer.py @@ -0,0 +1,21 @@ +# encoding: utf-8 + +import lldb + +class MyFrameRecognizer(object): +    def get_recognized_arguments(self, frame): +        if frame.name == "foo": +            arg1 = frame.EvaluateExpression("$arg1").signed +            arg2 = frame.EvaluateExpression("$arg2").signed +            val1 = lldb.target.CreateValueFromExpression("a", "%d" % arg1) +            val2 = lldb.target.CreateValueFromExpression("b", "%d" % arg2) +            return [val1, val2] +        elif frame.name == "bar": +            arg1 = frame.EvaluateExpression("$arg1").signed +            val1 = lldb.target.CreateValueFromExpression("a", "(int *)%d" % arg1) +            return [val1] +        return [] + +class MyOtherFrameRecognizer(object): +    def get_recognized_arguments(self, frame): +        return [] diff --git a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestArmRegisterDefinition.py b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestArmRegisterDefinition.py new file mode 100644 index 000000000000..6e28d5b54052 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestArmRegisterDefinition.py @@ -0,0 +1,130 @@ +from __future__ import print_function +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from gdbclientutils import * + +class TestArmRegisterDefinition(GDBRemoteTestBase): + +    @skipIfXmlSupportMissing +    @skipIfRemote +    def test(self): +        """ +        Test lldb's parsing of the <architecture> tag in the target.xml register +        description packet. +        """ +        class MyResponder(MockGDBServerResponder): + +            def qXferRead(self, obj, annex, offset, length): +                if annex == "target.xml": +                    return """<?xml version="1.0"?> +                        <!DOCTYPE feature SYSTEM "gdb-target.dtd"> +                        <target> +                        <architecture>arm</architecture> +                        <feature name="org.gnu.gdb.arm.m-profile"> +                        <reg name="r0" bitsize="32" type="uint32" group="general"/> +                        <reg name="r1" bitsize="32" type="uint32" group="general"/> +                        <reg name="r2" bitsize="32" type="uint32" group="general"/> +                        <reg name="r3" bitsize="32" type="uint32" group="general"/> +                        <reg name="r4" bitsize="32" type="uint32" group="general"/> +                        <reg name="r5" bitsize="32" type="uint32" group="general"/> +                        <reg name="r6" bitsize="32" type="uint32" group="general"/> +                        <reg name="r7" bitsize="32" type="uint32" group="general"/> +                        <reg name="r8" bitsize="32" type="uint32" group="general"/> +                        <reg name="r9" bitsize="32" type="uint32" group="general"/> +                        <reg name="r10" bitsize="32" type="uint32" group="general"/> +                        <reg name="r11" bitsize="32" type="uint32" group="general"/> +                        <reg name="r12" bitsize="32" type="uint32" group="general"/> +                        <reg name="sp" bitsize="32" type="data_ptr" group="general"/> +                        <reg name="lr" bitsize="32" type="uint32" group="general"/> +                        <reg name="pc" bitsize="32" type="code_ptr" group="general"/> +                        <reg name="xpsr" bitsize="32" regnum="25" type="uint32" group="general"/> +                        <reg name="MSP" bitsize="32" regnum="26" type="uint32" group="general"/> +                        <reg name="PSP" bitsize="32" regnum="27" type="uint32" group="general"/> +                        <reg name="PRIMASK" bitsize="32" regnum="28" type="uint32" group="general"/> +                        <reg name="BASEPRI" bitsize="32" regnum="29" type="uint32" group="general"/> +                        <reg name="FAULTMASK" bitsize="32" regnum="30" type="uint32" group="general"/> +                        <reg name="CONTROL" bitsize="32" regnum="31" type="uint32" group="general"/> +                        <reg name="FPSCR" bitsize="32" type="uint32" group="float"/> +                        <reg name="s0" bitsize="32" type="float" group="float"/> +                        <reg name="s1" bitsize="32" type="float" group="float"/> +                        <reg name="s2" bitsize="32" type="float" group="float"/> +                        <reg name="s3" bitsize="32" type="float" group="float"/> +                        <reg name="s4" bitsize="32" type="float" group="float"/> +                        <reg name="s5" bitsize="32" type="float" group="float"/> +                        <reg name="s6" bitsize="32" type="float" group="float"/> +                        <reg name="s7" bitsize="32" type="float" group="float"/> +                        <reg name="s8" bitsize="32" type="float" group="float"/> +                        <reg name="s9" bitsize="32" type="float" group="float"/> +                        <reg name="s10" bitsize="32" type="float" group="float"/> +                        <reg name="s11" bitsize="32" type="float" group="float"/> +                        <reg name="s12" bitsize="32" type="float" group="float"/> +                        <reg name="s13" bitsize="32" type="float" group="float"/> +                        <reg name="s14" bitsize="32" type="float" group="float"/> +                        <reg name="s15" bitsize="32" type="float" group="float"/> +                        <reg name="s16" bitsize="32" type="float" group="float"/> +                        <reg name="s17" bitsize="32" type="float" group="float"/> +                        <reg name="s18" bitsize="32" type="float" group="float"/> +                        <reg name="s19" bitsize="32" type="float" group="float"/> +                        <reg name="s20" bitsize="32" type="float" group="float"/> +                        <reg name="s21" bitsize="32" type="float" group="float"/> +                        <reg name="s22" bitsize="32" type="float" group="float"/> +                        <reg name="s23" bitsize="32" type="float" group="float"/> +                        <reg name="s24" bitsize="32" type="float" group="float"/> +                        <reg name="s25" bitsize="32" type="float" group="float"/> +                        <reg name="s26" bitsize="32" type="float" group="float"/> +                        <reg name="s27" bitsize="32" type="float" group="float"/> +                        <reg name="s28" bitsize="32" type="float" group="float"/> +                        <reg name="s29" bitsize="32" type="float" group="float"/> +                        <reg name="s30" bitsize="32" type="float" group="float"/> +                        <reg name="s31" bitsize="32" type="float" group="float"/> +                        </feature> +                        </target>""", False +                else: +                    return None, False + +            def readRegister(self, regnum): +                return "E01" + +            def readRegisters(self): +                return "20000000f8360020001000002fcb0008f8360020a0360020200c0020000000000000000000000000000000000000000000000000b87f0120b7d100082ed2000800000001b87f01200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + +            def haltReason(self): +                return "S05" + +            def qfThreadInfo(self): +                return "mdead" +             +            def qC(self): +                return "" + +            def qSupported(self, client_supported): +                return "PacketSize=4000;qXfer:memory-map:read-;QStartNoAckMode+;qXfer:threads:read+;hwbreak+;qXfer:features:read+" + +            def QThreadSuffixSupported(self): +                return "OK" + +            def QListThreadsInStopReply(self): +                return "OK" + +        self.server.responder = MyResponder() +        if self.TraceOn(): +            interp = self.dbg.GetCommandInterpreter() +            result = lldb.SBCommandReturnObject() +            interp.HandleCommand("log enable gdb-remote packets", result) +        self.dbg.SetDefaultArchitecture("armv7em") +        target = self.dbg.CreateTargetWithFileAndArch(None, None) + +        process = self.connect(target) + +        if self.TraceOn(): +            interp = self.dbg.GetCommandInterpreter() +            result = lldb.SBCommandReturnObject() +            interp.HandleCommand("target list", result) +            print(result.GetOutput()) + +        r0_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("r0") +        self.assertEqual(r0_valobj.GetValueAsUnsigned(), 0x20) + +        pc_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("pc") +        self.assertEqual(pc_valobj.GetValueAsUnsigned(), 0x0800d22e) diff --git a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py new file mode 100644 index 000000000000..66a271e126dc --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestNoWatchpointSupportInfo.py @@ -0,0 +1,64 @@ +from __future__ import print_function +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from gdbclientutils import * + +class TestNoWatchpointSupportInfo(GDBRemoteTestBase): + +    @skipIfXmlSupportMissing +    @skipIfRemote +    def test(self): +        """ +        Test lldb's parsing of the <architecture> tag in the target.xml register +        description packet. +        """ +        class MyResponder(MockGDBServerResponder): + +            def haltReason(self): +                return "T02thread:1ff0d;thread-pcs:10001bc00;" + +            def threadStopInfo(self, threadnum): +                if threadnum == 0x1ff0d: +                    return "T02thread:1ff0d;thread-pcs:10001bc00;" + +            def setBreakpoint(self, packet): +                if packet.startswith("Z2,"): +                    return "OK" + +            def qXferRead(self, obj, annex, offset, length): +                if annex == "target.xml": +                    return """<?xml version="1.0"?> +                        <target version="1.0"> +                          <architecture>i386:x86-64</architecture> +                          <feature name="org.gnu.gdb.i386.core"> +                            <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/> +                          </feature> +                        </target>""", False +                else: +                    return None, False + +        self.server.responder = MyResponder() +        if self.TraceOn(): +            interp = self.dbg.GetCommandInterpreter() +            result = lldb.SBCommandReturnObject() +            interp.HandleCommand("log enable gdb-remote packets", result) +        self.dbg.SetDefaultArchitecture("x86_64") +        target = self.dbg.CreateTargetWithFileAndArch(None, None) + +        process = self.connect(target) + +        if self.TraceOn(): +            interp = self.dbg.GetCommandInterpreter() +            result = lldb.SBCommandReturnObject() +            interp.HandleCommand("target list", result) +            print(result.GetOutput()) + +	 +        err = lldb.SBError() +        wp = target.WatchAddress(0x100, 8, False, True, err) +        if self.TraceOn() and (err.Fail() or wp.IsValid == False): +            strm = lldb.SBStream() +            err.GetDescription(strm) +            print("watchpoint failed: %s" % strm.GetData()) +        self.assertTrue(wp.IsValid()) diff --git a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestStopPCs.py b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestStopPCs.py new file mode 100644 index 000000000000..7b733e77e679 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestStopPCs.py @@ -0,0 +1,46 @@ +from __future__ import print_function +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from gdbclientutils import * + + +class TestStopPCs(GDBRemoteTestBase): + +    @skipIfXmlSupportMissing +    def test(self): +        class MyResponder(MockGDBServerResponder): +            def haltReason(self): +                return "T02thread:1ff0d;threads:1ff0d,2ff0d;thread-pcs:10001bc00,10002bc00;" + +            def threadStopInfo(self, threadnum): +                if threadnum == 0x1ff0d: +                    return "T02thread:1ff0d;threads:1ff0d,2ff0d;thread-pcs:10001bc00,10002bc00;" +                if threadnum == 0x2ff0d: +                    return "T00thread:2ff0d;threads:1ff0d,2ff0d;thread-pcs:10001bc00,10002bc00;" + +            def qXferRead(self, obj, annex, offset, length): +                if annex == "target.xml": +                    return """<?xml version="1.0"?> +                        <target version="1.0"> +                          <architecture>i386:x86-64</architecture> +                          <feature name="org.gnu.gdb.i386.core"> +                            <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/> +                          </feature> +                        </target>""", False +                else: +                    return None, False + +        self.server.responder = MyResponder() +        target = self.dbg.CreateTarget('') +        if self.TraceOn(): +          self.runCmd("log enable gdb-remote packets") +        process = self.connect(target) + +        self.assertEqual(process.GetNumThreads(), 2) +        th0 = process.GetThreadAtIndex(0) +        th1 = process.GetThreadAtIndex(1) +        self.assertEqual(th0.GetThreadID(), 0x1ff0d) +        self.assertEqual(th1.GetThreadID(), 0x2ff0d) +        self.assertEqual(th0.GetFrameAtIndex(0).GetPC(), 0x10001bc00) +        self.assertEqual(th1.GetFrameAtIndex(0).GetPC(), 0x10002bc00) diff --git a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py index 184867e480b4..57c5ff0aac25 100644 --- a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py +++ b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py @@ -121,4 +121,4 @@ class TestTargetXMLArch(GDBRemoteTestBase):          if self.TraceOn():              interp.HandleCommand("target list", result)              print(result.GetOutput()) -        self.assertTrue(target.GetTriple().startswith('x86_64--')) +        self.assertTrue(target.GetTriple().startswith('x86_64-unknown-unknown')) diff --git a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py index d8d759a5dd58..a9e553cbb7d5 100644 --- a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py +++ b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py @@ -102,12 +102,13 @@ class MockGDBServerResponder:              return self.interrupt()          if packet == "c":              return self.cont() -        if packet == "g": +        if packet[0] == "g":              return self.readRegisters()          if packet[0] == "G":              return self.writeRegisters(packet[1:])          if packet[0] == "p": -            return self.readRegister(int(packet[1:], 16)) +            regnum = packet[1:].split(';')[0] +            return self.readRegister(int(regnum, 16))          if packet[0] == "P":              register, value = packet[1:].split("=")              return self.readRegister(int(register, 16), value) @@ -124,12 +125,16 @@ class MockGDBServerResponder:              return self.qSupported(packet[11:].split(";"))          if packet == "qfThreadInfo":              return self.qfThreadInfo() +        if packet == "qsThreadInfo": +            return self.qsThreadInfo()          if packet == "qC":              return self.qC()          if packet == "QEnableErrorStrings":              return self.QEnableErrorStrings()          if packet == "?":              return self.haltReason() +        if packet == "s": +            return self.haltReason()          if packet[0] == "H":              return self.selectThread(packet[1], int(packet[2:], 16))          if packet[0:6] == "qXfer:": @@ -144,6 +149,16 @@ class MockGDBServerResponder:              return self.vAttach(int(pid, 16))          if packet[0] == "Z":              return self.setBreakpoint(packet) +        if packet.startswith("qThreadStopInfo"): +            threadnum = int (packet[15:], 16) +            return self.threadStopInfo(threadnum) +        if packet == "QThreadSuffixSupported": +            return self.QThreadSuffixSupported() +        if packet == "QListThreadsInStopReply": +            return self.QListThreadsInStopReply() +        if packet.startswith("qMemoryRegionInfo:"): +            return self.qMemoryRegionInfo() +          return self.other(packet)      def interrupt(self): @@ -179,6 +194,9 @@ class MockGDBServerResponder:      def qfThreadInfo(self):          return "l" +    def qsThreadInfo(self): +        return "l" +      def qC(self):          return "QC0" @@ -204,10 +222,22 @@ class MockGDBServerResponder:      def setBreakpoint(self, packet):          raise self.UnexpectedPacketException() +    def threadStopInfo(self, threadnum): +        return "" +      def other(self, packet):          # empty string means unsupported          return "" +    def QThreadSuffixSupported(self): +        return "" + +    def QListThreadsInStopReply(self): +        return "" + +    def qMemoryRegionInfo(self): +        return "" +      """      Raised when we receive a packet for which there is no default action.      Override the responder class to implement behavior suitable for the test at @@ -246,7 +276,7 @@ class MockGDBServer:          addr = ("127.0.0.1", self.port)          self._socket.bind(addr)          self.port = self._socket.getsockname()[1] -        self._socket.listen(0) +        self._socket.listen(1)          self._thread = threading.Thread(target=self._run)          self._thread.start() diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py index 4f54f5d4103b..528192519513 100644 --- a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py +++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/TestInferiorCrashing.py @@ -16,59 +16,42 @@ class CrashingInferiorTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API") +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      def test_inferior_crashing(self):          """Test that lldb reliably catches the inferior crashing (command)."""          self.build()          self.inferior_crashing() -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API") +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      def test_inferior_crashing_register(self):          """Test that lldb reliably reads registers from the inferior after crashing (command)."""          self.build()          self.inferior_crashing_registers()      @add_test_categories(['pyapi']) -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")      def test_inferior_crashing_python(self):          """Test that lldb reliably catches the inferior crashing (Python API)."""          self.build()          self.inferior_crashing_python() -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")      def test_inferior_crashing_expr(self):          """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""          self.build()          self.inferior_crashing_expr() -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API") +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      def test_inferior_crashing_step(self):          """Test that stepping after a crash behaves correctly."""          self.build()          self.inferior_crashing_step() -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")      @skipIfTargetAndroid()  # debuggerd interferes with this test on Android +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      def test_inferior_crashing_step_after_break(self):          """Test that lldb functions correctly after stepping through a crash."""          self.build()          self.inferior_crashing_step_after_break() -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24778, This actually works, but the test relies on the output format instead of the API")      # Inferior exits after stepping after a segfault. This is working as      # intended IMHO.      @skipIfLinux diff --git a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py index d8efe65dc7f6..2cd4d46a7ca8 100644 --- a/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py +++ b/packages/Python/lldbsuite/test/functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py @@ -29,13 +29,11 @@ class CrashingRecursiveInferiorTestCase(TestBase):          self.recursive_inferior_crashing_registers()      @add_test_categories(['pyapi']) -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      def test_recursive_inferior_crashing_python(self):          """Test that lldb reliably catches the inferior crashing (Python API)."""          self.build()          self.recursive_inferior_crashing_python() -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      def test_recursive_inferior_crashing_expr(self):          """Test that the lldb expression interpreter can read from the inferior after crashing (command)."""          self.build() @@ -47,8 +45,8 @@ class CrashingRecursiveInferiorTestCase(TestBase):          self.build()          self.recursive_inferior_crashing_step() -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      @skipIfTargetAndroid()  # debuggerd interferes with this test on Android +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      def test_recursive_inferior_crashing_step_after_break(self):          """Test that lldb functions correctly after stepping through a crash."""          self.build() @@ -58,7 +56,6 @@ class CrashingRecursiveInferiorTestCase(TestBase):      # intended IMHO.      @skipIfLinux      @skipIfFreeBSD -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      def test_recursive_inferior_crashing_expr_step_and_expr(self):          """Test that lldb expressions work before and after stepping after a crash."""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py b/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py index ab5791c614af..7bc5d205a94f 100644 --- a/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py +++ b/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py @@ -158,6 +158,7 @@ class LoadUnloadTestCase(TestBase):      @skipIfFreeBSD  # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support      @expectedFailureAndroid  # wrong source file shows up for hidden library      @skipIfWindows  # Windows doesn't have dlopen and friends, dynamic libraries work differently +    @skipIfDarwinEmbedded      def test_dyld_library_path(self):          """Test (DY)LD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else."""          self.copy_shlibs_to_remote(hidden_dir=True) diff --git a/packages/Python/lldbsuite/test/functionalities/memory-region/Makefile b/packages/Python/lldbsuite/test/functionalities/memory-region/Makefile new file mode 100644 index 000000000000..9d4f3b7f1412 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/memory-region/Makefile @@ -0,0 +1,8 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules + +clean:: +	rm -rf $(wildcard *.o *.d *.dSYM) diff --git a/packages/Python/lldbsuite/test/functionalities/memory-region/TestMemoryRegion.py b/packages/Python/lldbsuite/test/functionalities/memory-region/TestMemoryRegion.py new file mode 100644 index 000000000000..4d10e68672e0 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/memory-region/TestMemoryRegion.py @@ -0,0 +1,59 @@ +""" +Test the 'memory region' command. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class MemoryCommandRegion(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    NO_DEBUG_INFO_TESTCASE = True + +    def setUp(self): +        TestBase.setUp(self) +        # Find the line number to break for main.c. +        self.line = line_number( +            'main.cpp', +            '// Run here before printing memory regions') + +    def test(self): +        self.build() + +        # Set breakpoint in main and run +        self.runCmd("file " + self.getBuildArtifact("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) + +        interp = self.dbg.GetCommandInterpreter() +        result = lldb.SBCommandReturnObject() + +        # Test that the first 'memory region' command prints the usage. +        interp.HandleCommand("memory region", result) +        self.assertFalse(result.Succeeded()) +        self.assertRegexpMatches(result.GetError(), "Usage: memory region ADDR") + +        # Now let's print the memory region starting at 0 which should always work. +        interp.HandleCommand("memory region 0x0", result) +        self.assertTrue(result.Succeeded()) +        self.assertRegexpMatches(result.GetOutput(), "\\[0x0+-") + +        # Keep printing memory regions until we printed all of them. +        while True: +            interp.HandleCommand("memory region", result) +            if not result.Succeeded(): +                break + +        # Now that we reached the end, 'memory region' should again print the usage. +        interp.HandleCommand("memory region", result) +        self.assertFalse(result.Succeeded()) +        self.assertRegexpMatches(result.GetError(), "Usage: memory region ADDR") diff --git a/packages/Python/lldbsuite/test/functionalities/memory-region/main.cpp b/packages/Python/lldbsuite/test/functionalities/memory-region/main.cpp new file mode 100644 index 000000000000..116c10a6c3ea --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/memory-region/main.cpp @@ -0,0 +1,6 @@ +#include <iostream> + +int main (int argc, char const **argv) { +  std::cout << "Program with sections" << std::endl; +  return 0; // Run here before printing memory regions +} diff --git a/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py b/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py index f45479bee0bf..56984885104e 100644 --- a/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py +++ b/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py @@ -24,7 +24,7 @@ class MemoryCacheTestCase(TestBase):          # Find the line number to break inside main().          self.line = line_number('main.cpp', '// Set break point at this line.') -    @expectedFlakeyOS(oslist=["windows"]) +    @skipIfWindows # This is flakey on Windows: llvm.org/pr38373      def test_memory_cache(self):          """Test the MemoryCache class with a sequence of 'memory read' and 'memory write' operations."""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/memory/find/TestMemoryFind.py b/packages/Python/lldbsuite/test/functionalities/memory/find/TestMemoryFind.py index 8e0fbaa32018..245aaa819c7f 100644 --- a/packages/Python/lldbsuite/test/functionalities/memory/find/TestMemoryFind.py +++ b/packages/Python/lldbsuite/test/functionalities/memory/find/TestMemoryFind.py @@ -24,7 +24,6 @@ class MemoryFindTestCase(TestBase):          # Find the line number to break inside main().          self.line = line_number('main.cpp', '// break here') -    @expectedFailureAll(oslist=["windows"])      def test_memory_find(self):          """Test the 'memory find' command."""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py b/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py index 879f1adebc6a..2c25ccc253fd 100644 --- a/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -6,6 +6,7 @@ from __future__ import print_function  import shutil  import struct +import os  import lldb  from lldbsuite.test.decorators import * @@ -203,6 +204,30 @@ class LinuxCoreTestCase(TestBase):          for regname, value in values.iteritems():              self.expect("register read {}".format(regname), substrs=["{} = {}".format(regname, value)]) +    @expectedFailureAll(bugnumber="llvm.org/pr37371", hostoslist=["windows"]) +    @skipIf(triple='^mips') +    @skipIfLLVMTargetMissing("X86") +    def test_i386_sysroot(self): +        """Test that lldb can find the exe for an i386 linux core file using the sysroot.""" + +        # Copy linux-i386.out to tmp_sysroot/home/labath/test/a.out (since it was compiled as +        # /home/labath/test/a.out) +        tmp_sysroot = os.path.join(self.getBuildDir(), "lldb_i386_mock_sysroot") +        executable = os.path.join(tmp_sysroot, "home", "labath", "test", "a.out") +        lldbutil.mkdir_p(os.path.dirname(executable)) +        shutil.copyfile("linux-i386.out", executable) + +        # Set sysroot and load core +        self.runCmd("platform select remote-linux --sysroot '%s'" % tmp_sysroot) +        target = self.dbg.CreateTarget(None) +        self.assertTrue(target, VALID_TARGET) +        process = target.LoadCore("linux-i386.core") + +        # Check that we found a.out from the sysroot +        self.check_all(process, self._i386_pid, self._i386_regions, "a.out") + +        self.dbg.DeleteTarget(target) +      def check_memory_regions(self, process, region_count):          region_list = process.GetMemoryRegions()          self.assertEqual(region_list.GetSize(), region_count) @@ -299,15 +324,7 @@ class LinuxCoreTestCase(TestBase):              self.dbg.SetOutputFileHandle(None, False)              self.dbg.SetErrorFileHandle(None, False) -    def do_test(self, filename, pid, region_count, thread_name): -        target = self.dbg.CreateTarget(filename + ".out") -        process = target.LoadCore(filename + ".core") -        self.assertTrue(process, PROCESS_IS_VALID) -        self.assertEqual(process.GetNumThreads(), 1) -        self.assertEqual(process.GetProcessID(), pid) - -        self.check_state(process) - +    def check_stack(self, process, pid, thread_name):          thread = process.GetSelectedThread()          self.assertTrue(thread)          self.assertEqual(thread.GetThreadID(), pid) @@ -324,6 +341,21 @@ class LinuxCoreTestCase(TestBase):                  frame.FindVariable("F").GetValueAsUnsigned(), ord(                      backtrace[i][0])) +    def check_all(self, process, pid, region_count, thread_name): +        self.assertTrue(process, PROCESS_IS_VALID) +        self.assertEqual(process.GetNumThreads(), 1) +        self.assertEqual(process.GetProcessID(), pid) + +        self.check_state(process) + +        self.check_stack(process, pid, thread_name) +          self.check_memory_regions(process, region_count) +    def do_test(self, filename, pid, region_count, thread_name): +        target = self.dbg.CreateTarget(filename + ".out") +        process = target.LoadCore(filename + ".core") + +        self.check_all(process, pid, region_count, thread_name) +          self.dbg.DeleteTarget(target) diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py index 5960215f8047..46398e39a0e0 100644 --- a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py @@ -88,6 +88,36 @@ class MiniDumpNewTestCase(TestBase):          self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)          self.check_state() +    def test_memory_region_name(self): +        self.dbg.CreateTarget(None) +        self.target = self.dbg.GetSelectedTarget() +        self.process = self.target.LoadCore("regions-linux-map.dmp") +        result = lldb.SBCommandReturnObject() +        addr_region_name_pairs = [ +            ("0x400d9000", "/system/bin/app_process"), +            ("0x400db000", "/system/bin/app_process"), +            ("0x400dd000", "/system/bin/linker"), +            ("0x400ed000", "/system/bin/linker"), +            ("0x400ee000", "/system/bin/linker"), +            ("0x400fb000", "/system/lib/liblog.so"), +            ("0x400fc000", "/system/lib/liblog.so"), +            ("0x400fd000", "/system/lib/liblog.so"), +            ("0x400ff000", "/system/lib/liblog.so"), +            ("0x40100000", "/system/lib/liblog.so"), +            ("0x40101000", "/system/lib/libc.so"), +            ("0x40122000", "/system/lib/libc.so"), +            ("0x40123000", "/system/lib/libc.so"), +            ("0x40167000", "/system/lib/libc.so"), +            ("0x40169000", "/system/lib/libc.so"), +        ] +        ci = self.dbg.GetCommandInterpreter() +        for (addr, region_name) in addr_region_name_pairs: +            command = 'memory region ' + addr +            ci.HandleCommand(command, result, False) +            message = 'Ensure memory "%s" shows up in output for "%s"' % ( +                region_name, command) +            self.assertTrue(region_name in result.GetOutput(), message) +      def test_modules_in_mini_dump(self):          """Test that lldb can read the list of modules from the minidump."""          # target create -c linux-x86_64.dmp @@ -97,14 +127,18 @@ class MiniDumpNewTestCase(TestBase):          self.assertTrue(self.process, PROCESS_IS_VALID)          expected_modules = [              { -                'filename' : 'linux-gate.so', -                'uuid' : '4EAD28F8-88EF-3520-872B-73C6F2FE7306-C41AF22F', +                'filename' : 'linux-x86_64', +                'uuid' : 'E35C283B-C327-C287-62DB-788BF5A4078B-E2351448',              },              {                  'filename' : 'libm-2.19.so',                  'uuid' : 'D144258E-6149-00B2-55A3-1F3FD2283A87-8670D5BC',              },              { +                'filename' : 'libgcc_s.so.1', +                'uuid' : '36311B44-5771-0AE5-578C-4BF00791DED7-359DBB92', +            }, +            {                  'filename' : 'libstdc++.so.6.0.19',                  'uuid' : '76190E92-2AF7-457D-078F-75C9B15FA184-E83EB506',              }, @@ -113,24 +147,20 @@ class MiniDumpNewTestCase(TestBase):                  'uuid' : 'CF699A15-CAAE-64F5-0311-FC4655B86DC3-9A479789',              },              { -                'filename' : 'linux-x86_64', -                'uuid' : 'E35C283B-C327-C287-62DB-788BF5A4078B-E2351448', -            }, -            { -                'filename' : 'libgcc_s.so.1', -                'uuid' : '36311B44-5771-0AE5-578C-4BF00791DED7-359DBB92', -            }, -            {                  'filename' : 'libpthread-2.19.so',                  'uuid' : '31E9F21A-E8C1-0396-171F-1E13DA157809-86FA696C',              },              { +                'filename' : 'libbreakpad.so', +                'uuid' : '784FD549-332D-826E-D23F-18C17C6F320A', +            }, +            {                  'filename' : 'ld-2.19.so',                  'uuid' : 'D0F53790-4076-D73F-29E4-A37341F8A449-E2EF6CD0',              },              { -                'filename' : 'libbreakpad.so', -                'uuid' : '784FD549-332D-826E-D23F-18C17C6F320A', +                'filename' : 'linux-gate.so', +                'uuid' : '4EAD28F8-88EF-3520-872B-73C6F2FE7306-C41AF22F',              },          ]          self.assertEqual(self.target.GetNumModules(), len(expected_modules)) @@ -189,6 +219,161 @@ class MiniDumpNewTestCase(TestBase):          stop_description = thread.GetStopDescription(256)          self.assertEqual(stop_description, "") +    def check_register_unsigned(self, set, name, expected): +        reg_value = set.GetChildMemberWithName(name) +        self.assertTrue(reg_value.IsValid(), +                        'Verify we have a register named "%s"' % (name)) +        self.assertEqual(reg_value.GetValueAsUnsigned(), expected, +                         'Verify "%s" == %i' % (name, expected)) + +    def check_register_string_value(self, set, name, expected, format): +        reg_value = set.GetChildMemberWithName(name) +        self.assertTrue(reg_value.IsValid(), +                        'Verify we have a register named "%s"' % (name)) +        if format is not None: +            reg_value.SetFormat(format) +        self.assertEqual(reg_value.GetValue(), expected, +                         'Verify "%s" has string value "%s"' % (name, +                                                                expected)) + +    def test_arm64_registers(self): +        """Test ARM64 registers from a breakpad created minidump.""" +        # target create -c arm64-macos.dmp +        self.dbg.CreateTarget(None) +        self.target = self.dbg.GetSelectedTarget() +        self.process = self.target.LoadCore("arm64-macos.dmp") +        self.check_state() +        self.assertEqual(self.process.GetNumThreads(), 1) +        thread = self.process.GetThreadAtIndex(0) +        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone) +        stop_description = thread.GetStopDescription(256) +        self.assertEqual(stop_description, "") +        registers = thread.GetFrameAtIndex(0).GetRegisters() +        # Verify the GPR registers are all correct +        # Verify x0 - x31 register values +        gpr = registers.GetValueAtIndex(0) +        for i in range(32): +            v = i+1 | i+2 << 32 | i+3 << 48 +            w = i+1 +            self.check_register_unsigned(gpr, 'x%i' % (i), v) +            self.check_register_unsigned(gpr, 'w%i' % (i), w) +        # Verify arg1 - arg8 register values +        for i in range(1, 9): +            v = i | i+1 << 32 | i+2 << 48 +            self.check_register_unsigned(gpr, 'arg%i' % (i), v) +        i = 29 +        v = i+1 | i+2 << 32 | i+3 << 48 +        self.check_register_unsigned(gpr, 'fp', v) +        i = 30 +        v = i+1 | i+2 << 32 | i+3 << 48 +        self.check_register_unsigned(gpr, 'lr', v) +        i = 31 +        v = i+1 | i+2 << 32 | i+3 << 48 +        self.check_register_unsigned(gpr, 'sp', v) +        self.check_register_unsigned(gpr, 'pc', 0x1000) +        self.check_register_unsigned(gpr, 'cpsr', 0x11223344) +        self.check_register_unsigned(gpr, 'psr', 0x11223344) + +        # Verify the FPR registers are all correct +        fpr = registers.GetValueAtIndex(1) +        for i in range(32): +            v = "0x" +            d = "0x" +            s = "0x" +            h = "0x" +            for j in range(i+15, i-1, -1): +                v += "%2.2x" % (j) +            for j in range(i+7, i-1, -1): +                d += "%2.2x" % (j) +            for j in range(i+3, i-1, -1): +                s += "%2.2x" % (j) +            for j in range(i+1, i-1, -1): +                h += "%2.2x" % (j) +            self.check_register_string_value(fpr, "v%i" % (i), v, +                                             lldb.eFormatHex) +            self.check_register_string_value(fpr, "d%i" % (i), d, +                                             lldb.eFormatHex) +            self.check_register_string_value(fpr, "s%i" % (i), s, +                                             lldb.eFormatHex) +            self.check_register_string_value(fpr, "h%i" % (i), h, +                                             lldb.eFormatHex) +        self.check_register_unsigned(gpr, 'fpsr', 0x55667788) +        self.check_register_unsigned(gpr, 'fpcr', 0x99aabbcc) + +    def verify_arm_registers(self, apple=False): +        """ +            Verify values of all ARM registers from a breakpad created +            minidump. +        """ +        self.dbg.CreateTarget(None) +        self.target = self.dbg.GetSelectedTarget() +        if apple: +            self.process = self.target.LoadCore("arm-macos.dmp") +        else: +            self.process = self.target.LoadCore("arm-linux.dmp") +        self.check_state() +        self.assertEqual(self.process.GetNumThreads(), 1) +        thread = self.process.GetThreadAtIndex(0) +        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone) +        stop_description = thread.GetStopDescription(256) +        self.assertEqual(stop_description, "") +        registers = thread.GetFrameAtIndex(0).GetRegisters() +        # Verify the GPR registers are all correct +        # Verify x0 - x31 register values +        gpr = registers.GetValueAtIndex(0) +        for i in range(1, 16): +            self.check_register_unsigned(gpr, 'r%i' % (i), i+1) +        # Verify arg1 - arg4 register values +        for i in range(1, 5): +            self.check_register_unsigned(gpr, 'arg%i' % (i), i) +        if apple: +            self.check_register_unsigned(gpr, 'fp', 0x08) +        else: +            self.check_register_unsigned(gpr, 'fp', 0x0c) +        self.check_register_unsigned(gpr, 'lr', 0x0f) +        self.check_register_unsigned(gpr, 'sp', 0x0e) +        self.check_register_unsigned(gpr, 'pc', 0x10) +        self.check_register_unsigned(gpr, 'cpsr', 0x11223344) + +        # Verify the FPR registers are all correct +        fpr = registers.GetValueAtIndex(1) +        # Check d0 - d31 +        self.check_register_unsigned(gpr, 'fpscr', 0x55667788aabbccdd) +        for i in range(32): +            value = (i+1) | (i+1) << 8 | (i+1) << 32 | (i+1) << 48 +            self.check_register_unsigned(fpr, "d%i" % (i), value) +        # Check s0 - s31 +        for i in range(32): +            i_val = (i >> 1) + 1 +            if i & 1: +                value = "%#8.8x" % (i_val | i_val << 16) +            else: +                value = "%#8.8x" % (i_val | i_val << 8) +            self.check_register_string_value(fpr, "s%i" % (i), value, +                                             lldb.eFormatHex) +        # Check q0 - q15 +        for i in range(15): +            a = i * 2 + 1 +            b = a + 1 +            value = ("0x00%2.2x00%2.2x0000%2.2x%2.2x" +                     "00%2.2x00%2.2x0000%2.2x%2.2x") % (b, b, b, b, a, a, a, a) +            self.check_register_string_value(fpr, "q%i" % (i), value, +                                             lldb.eFormatHex) + +    def test_linux_arm_registers(self): +        """Test Linux ARM registers from a breakpad created minidump. + +           The frame pointer is R11 for linux. +        """ +        self.verify_arm_registers(apple=False) + +    def test_apple_arm_registers(self): +        """Test Apple ARM registers from a breakpad created minidump. + +           The frame pointer is R7 for linux. +        """ +        self.verify_arm_registers(apple=True) +      def do_test_deeper_stack(self, binary, core, pid):          target = self.dbg.CreateTarget(binary)          process = target.LoadCore(core) @@ -263,3 +448,65 @@ class MiniDumpNewTestCase(TestBase):          frame = thread.GetFrameAtIndex(1)          value = frame.EvaluateExpression('x')          self.assertEqual(value.GetValueAsSigned(), 3) + +    def test_memory_regions_in_minidump(self): +        """Test memory regions from a Minidump""" +        # target create -c regions-linux-map.dmp +        self.dbg.CreateTarget(None) +        self.target = self.dbg.GetSelectedTarget() +        self.process = self.target.LoadCore("regions-linux-map.dmp") +        self.check_state() + +        regions_count = 19 +        region_info_list = self.process.GetMemoryRegions() +        self.assertEqual(region_info_list.GetSize(), regions_count) + +        def check_region(index, start, end, read, write, execute, mapped, name): +            region_info = lldb.SBMemoryRegionInfo() +            self.assertTrue( +                self.process.GetMemoryRegionInfo(start, region_info).Success()) +            self.assertEqual(start, region_info.GetRegionBase()) +            self.assertEqual(end, region_info.GetRegionEnd()) +            self.assertEqual(read, region_info.IsReadable()) +            self.assertEqual(write, region_info.IsWritable()) +            self.assertEqual(execute, region_info.IsExecutable()) +            self.assertEqual(mapped, region_info.IsMapped()) +            self.assertEqual(name, region_info.GetName()) + +            # Ensure we have the same regions as SBMemoryRegionInfoList contains. +            if index >= 0 and index < regions_count: +                region_info_from_list = lldb.SBMemoryRegionInfo() +                self.assertTrue(region_info_list.GetMemoryRegionAtIndex( +                    index, region_info_from_list)) +                self.assertEqual(region_info_from_list, region_info) + +        a = "/system/bin/app_process" +        b = "/system/bin/linker" +        c = "/system/lib/liblog.so" +        d = "/system/lib/libc.so" +        n = None +        max_int = 0xffffffffffffffff + +        # Test address before the first entry comes back with nothing mapped up +        # to first valid region info +        check_region(-1, 0x00000000, 0x400d9000, False, False, False, False, n) +        check_region( 0, 0x400d9000, 0x400db000, True,  False, True,  True,  a) +        check_region( 1, 0x400db000, 0x400dc000, True,  False, False, True,  a) +        check_region( 2, 0x400dc000, 0x400dd000, True,  True,  False, True,  n) +        check_region( 3, 0x400dd000, 0x400ec000, True,  False, True,  True,  b) +        check_region( 4, 0x400ec000, 0x400ed000, True,  False, False, True,  n) +        check_region( 5, 0x400ed000, 0x400ee000, True,  False, False, True,  b) +        check_region( 6, 0x400ee000, 0x400ef000, True,  True,  False, True,  b) +        check_region( 7, 0x400ef000, 0x400fb000, True,  True,  False, True,  n) +        check_region( 8, 0x400fb000, 0x400fc000, True,  False, True,  True,  c) +        check_region( 9, 0x400fc000, 0x400fd000, True,  True,  True,  True,  c) +        check_region(10, 0x400fd000, 0x400ff000, True,  False, True,  True,  c) +        check_region(11, 0x400ff000, 0x40100000, True,  False, False, True,  c) +        check_region(12, 0x40100000, 0x40101000, True,  True,  False, True,  c) +        check_region(13, 0x40101000, 0x40122000, True,  False, True,  True,  d) +        check_region(14, 0x40122000, 0x40123000, True,  True,  True,  True,  d) +        check_region(15, 0x40123000, 0x40167000, True,  False, True,  True,  d) +        check_region(16, 0x40167000, 0x40169000, True,  False, False, True,  d) +        check_region(17, 0x40169000, 0x4016b000, True,  True,  False, True,  d) +        check_region(18, 0x4016b000, 0x40176000, True,  True,  False, True,  n) +        check_region(-1, 0x40176000, max_int,    False, False, False, False, n) diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp Binary files differnew file mode 100644 index 000000000000..3b0cb8268def --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp Binary files differnew file mode 100644 index 000000000000..9ff6a8396ec5 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp Binary files differnew file mode 100644 index 000000000000..ba658dd48feb --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/regions-linux-map.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/regions-linux-map.dmp Binary files differnew file mode 100644 index 000000000000..3f1dd53d98fa --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/regions-linux-map.dmp diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py index 61e2adee41d5..fe13871ddac9 100644 --- a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py @@ -50,28 +50,28 @@ class MiniDumpTestCase(TestBase):          self.assertTrue(self.process, PROCESS_IS_VALID)          expected_modules = [              { -                'filename' : r"C:\Windows\System32/MSVCP120D.dll", -                'uuid' : '6E51053C-E757-EB40-8D3F-9722C5BD80DD-01000000', -            }, -            { -                'filename' : r"C:\Windows\SysWOW64/kernel32.dll", -                'uuid' : '1B7ECBE5-5E00-1341-AB98-98D6913B52D8-02000000', -            }, -            {                  'filename' : r"C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug/fizzbuzz.exe",                  'uuid' : '91B7450F-969A-F946-BF8F-2D6076EA421A-11000000',              },              { -                'filename' : r"C:\Windows\System32/MSVCR120D.dll", -                'uuid' : '86FB8263-C446-4640-AE42-8D97B3F91FF2-01000000', +                'filename' : r"C:\Windows\SysWOW64/ntdll.dll", +                'uuid' : '6A84B0BB-2C40-5240-A16B-67650BBFE6B0-02000000', +            }, +            { +                'filename' : r"C:\Windows\SysWOW64/kernel32.dll", +                'uuid' : '1B7ECBE5-5E00-1341-AB98-98D6913B52D8-02000000',              },              {                  'filename' : r"C:\Windows\SysWOW64/KERNELBASE.dll",                  'uuid' : '4152F90B-0DCB-D44B-AC5D-186A6452E522-01000000',              },              { -                'filename' : r"C:\Windows\SysWOW64/ntdll.dll", -                'uuid' : '6A84B0BB-2C40-5240-A16B-67650BBFE6B0-02000000', +                'filename' : r"C:\Windows\System32/MSVCP120D.dll", +                'uuid' : '6E51053C-E757-EB40-8D3F-9722C5BD80DD-01000000', +            }, +            { +                'filename' : r"C:\Windows\System32/MSVCR120D.dll", +                'uuid' : '86FB8263-C446-4640-AE42-8D97B3F91FF2-01000000',              },          ]          self.assertEqual(self.target.GetNumModules(), len(expected_modules)) @@ -80,7 +80,6 @@ class MiniDumpTestCase(TestBase):              self.assertEqual(module.file.fullpath, expected['filename'])              self.assertEqual(module.GetUUIDString(), expected['uuid']) -    @expectedFailureAll(bugnumber="llvm.org/pr35193", hostoslist=["windows"])      def test_stack_info_in_mini_dump(self):          """Test that we can see a trivial stack in a VS-generate mini dump."""          # target create -c fizzbuzz_no_heap.dmp diff --git a/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py b/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py index 617b4bcfaec3..f485c13fa9f1 100644 --- a/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py +++ b/packages/Python/lldbsuite/test/functionalities/process_attach/TestProcessAttach.py @@ -23,7 +23,6 @@ class ProcessAttachTestCase(TestBase):      NO_DEBUG_INFO_TESTCASE = True      @skipIfiOSSimulator -    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], bugnumber="<rdar://problem/34538611>") # old lldb-server has race condition, launching an inferior and then launching debugserver in quick succession sometimes fails      def test_attach_to_process_by_id(self):          """Test attach by process id"""          self.build() @@ -40,7 +39,6 @@ class ProcessAttachTestCase(TestBase):          process = target.GetProcess()          self.assertTrue(process, PROCESS_IS_VALID) -    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], bugnumber="<rdar://problem/34538611>") # old lldb-server has race condition, launching an inferior and then launching debugserver in quick succession sometimes fails      def test_attach_to_process_from_different_dir_by_id(self):          """Test attach by process id"""          newdir = self.getBuildArtifact("newdir") @@ -67,7 +65,6 @@ class ProcessAttachTestCase(TestBase):          process = target.GetProcess()          self.assertTrue(process, PROCESS_IS_VALID) -    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], bugnumber="<rdar://problem/34538611>") # old lldb-server has race condition, launching an inferior and then launching debugserver in quick succession sometimes fails      def test_attach_to_process_by_name(self):          """Test attach by process name"""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py b/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py index 8496ce6c04d7..d3b153270119 100644 --- a/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py +++ b/packages/Python/lldbsuite/test/functionalities/process_group/TestChangeProcessGroup.py @@ -24,7 +24,6 @@ class ChangeProcessGroupTestCase(TestBase):      @skipIfFreeBSD  # Times out on FreeBSD llvm.org/pr23731      @skipIfWindows  # setpgid call does not exist on Windows      @expectedFailureAndroid("http://llvm.org/pr23762", api_levels=[16]) -    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], bugnumber="<rdar://problem/34538611>") # old lldb-server has race condition, launching an inferior and then launching debugserver in quick succession sometimes fails      def test_setpgid(self):          self.build()          exe = self.getBuildArtifact("a.out") diff --git a/packages/Python/lldbsuite/test/functionalities/register/intel_avx/TestYMMRegister.py b/packages/Python/lldbsuite/test/functionalities/register/intel_avx/TestYMMRegister.py index d362e6a8ae3d..1919d4b1ac6d 100644 --- a/packages/Python/lldbsuite/test/functionalities/register/intel_avx/TestYMMRegister.py +++ b/packages/Python/lldbsuite/test/functionalities/register/intel_avx/TestYMMRegister.py @@ -21,7 +21,6 @@ class TestYMMRegister(TestBase):      @skipIfiOSSimulator      @skipIfTargetAndroid()      @skipIf(archs=no_match(['i386', 'x86_64'])) -    @expectedFailureAll(oslist=["linux"], bugnumber="rdar://30523153")      @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr37995")      def test(self):          self.build(dictionary={"CFLAGS_EXTRAS": "-march=haswell"}) diff --git a/packages/Python/lldbsuite/test/functionalities/show_location/TestShowLocationDwarf5.py b/packages/Python/lldbsuite/test/functionalities/show_location/TestShowLocationDwarf5.py new file mode 100644 index 000000000000..a56282efd77d --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/show_location/TestShowLocationDwarf5.py @@ -0,0 +1,34 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * + +# This test checks that source code location is shown correctly +# when DWARF5 debug information is used. + +class TestTargetSourceMap(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    def test_source_map(self): +        # Set the target soure map to map "./" to the current test directory. +        yaml_path = os.path.join(self.getSourceDir(), "a.yaml") +        yaml_base, ext = os.path.splitext(yaml_path) +        obj_path = self.getBuildArtifact(yaml_base) +        self.yaml2obj(yaml_path, obj_path) + +        def cleanup(): +            if os.path.exists(obj_path): +                os.unlink(obj_path) + +        # Execute the cleanup function during test case tear down. +        self.addTearDownHook(cleanup) + +        # Create a target with the object file we just created from YAML +        target = self.dbg.CreateTarget(obj_path) + +        # Check we are able to show the locations properly. +        self.expect("b main", VALID_BREAKPOINT_LOCATION, +                    substrs=['main + 13 at test.cpp:2:3, address = 0x000000000040052d']) + +        self.expect("b foo", VALID_BREAKPOINT_LOCATION, +                    substrs=['foo() + 4 at test.cpp:6:1, address = 0x0000000000400534']) diff --git a/packages/Python/lldbsuite/test/functionalities/show_location/a.yaml b/packages/Python/lldbsuite/test/functionalities/show_location/a.yaml new file mode 100644 index 000000000000..27b119d3df63 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/show_location/a.yaml @@ -0,0 +1,58 @@ +# This file is a shorten version of the output +# produced with the following invocations and input: +# ./clang test.cpp -g -gdwarf-5 -o test.exe +# ./obj2yaml test.exe > test.yaml +# +# // test.cpp +# int main() { +#   return 0; +# } +#  +# void foo() { +# } + +--- !ELF +FileHeader:       +  Class:           ELFCLASS64 +  Data:            ELFDATA2LSB +  Type:            ET_EXEC +  Machine:         EM_X86_64 +  Entry:           0x0000000000400440 +Sections:         +  - Name:            .text +    Type:            SHT_PROGBITS +    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ] +    Address:         0x0000000000400440 +    AddressAlign:    0x0000000000000010 +    Content:         31ED4989D15E4889E24883E4F0505449C7C0B005400048C7C14005400048C7C720054000E8B7FFFFFFF4660F1F44000055B820204000483D202040004889E57417B8000000004885C0740D5DBF20204000FFE00F1F4400005DC3660F1F440000BE20204000554881EE202040004889E548C1FE034889F048C1E83F4801C648D1FE7415B8000000004885C0740B5DBF20204000FFE00F1F005DC3660F1F440000803D391B0000007517554889E5E87EFFFFFFC605271B0000015DC30F1F440000F3C30F1F4000662E0F1F840000000000554889E55DEB89660F1F840000000000554889E531C0C745FC000000005DC390554889E55DC3662E0F1F840000000000415741564189FF415541544C8D25B618000055488D2DB6180000534989F64989D54C29E54883EC0848C1FD03E87FFEFFFF4885ED742031DB0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3 +  - Name:            .debug_str_offsets +    Type:            SHT_PROGBITS +    AddressAlign:    0x0000000000000001 +    Content:         200000000500000000000000230000002C0000004A0000004F000000530000005B000000 +  - Name:            .debug_str +    Type:            SHT_PROGBITS +    Flags:           [ SHF_MERGE, SHF_STRINGS ] +    AddressAlign:    0x0000000000000001 +    Content:         636C616E672076657273696F6E20382E302E3020287472756E6B203334313935382900746573742E637070002F686F6D652F756D622F4C4C564D2F6275696C645F6C6C64622F62696E006D61696E00696E74005F5A33666F6F7600666F6F00 +  - Name:            .debug_abbrev +    Type:            SHT_PROGBITS +    AddressAlign:    0x0000000000000001 +    Content:         011101252513050325721710171B25110112060000022E0011011206401803253A0B3B0B49133F190000032E001101120640186E2503253A0B3B0B3F19000004240003253E0B0B0B000000 +  - Name:            .debug_info +    Type:            SHT_PROGBITS +    AddressAlign:    0x0000000000000001 +    Content:         50000000050001080000000001000400010800000000000000022005400000000000160000000220054000000000000F00000001560301014F000000033005400000000000060000000156050601050404050400 +  - Name:            .debug_macinfo +    Type:            SHT_PROGBITS +    AddressAlign:    0x0000000000000001 +    Content:         '00' +  - Name:            .debug_line +    Type:            SHT_PROGBITS +    AddressAlign:    0x0000000000000001 +    Content:         70000000050008004C000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E021E00000000FD7C0F2E46BA561F7BDA351B04E677091E00000000FD7C0F2E46BA561F7BDA351B04E6770900090220054000000000000105030AC905003F05010A4B0202000101 +  - Name:            .debug_line_str +    Type:            SHT_PROGBITS +    Flags:           [ SHF_MERGE, SHF_STRINGS ] +    AddressAlign:    0x0000000000000001 +    Content:         2F686F6D652F756D622F4C4C564D2F6275696C645F6C6C64622F62696E00746573742E63707000 +... diff --git a/packages/Python/lldbsuite/test/functionalities/stats_api/TestStatisticsAPI.py b/packages/Python/lldbsuite/test/functionalities/stats_api/TestStatisticsAPI.py index a6c38ca1d091..f2027eb131c5 100644 --- a/packages/Python/lldbsuite/test/functionalities/stats_api/TestStatisticsAPI.py +++ b/packages/Python/lldbsuite/test/functionalities/stats_api/TestStatisticsAPI.py @@ -17,6 +17,15 @@ class TestStatsAPI(TestBase):          self.build()          exe = self.getBuildArtifact("a.out")          target = self.dbg.CreateTarget(exe) + +        # Test enabling/disabling stats +        self.assertFalse(target.GetCollectingStats()) +        target.SetCollectingStats(True) +        self.assertTrue(target.GetCollectingStats()) +        target.SetCollectingStats(False) +        self.assertFalse(target.GetCollectingStats()) + +        # Test the function to get the statistics in JSON'ish.          stats = target.GetStatistics()          stream = lldb.SBStream()          res = stats.GetAsJSON(stream) diff --git a/packages/Python/lldbsuite/test/functionalities/step_scripted/Makefile b/packages/Python/lldbsuite/test/functionalities/step_scripted/Makefile new file mode 100644 index 000000000000..0d70f2595019 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/step_scripted/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py b/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py new file mode 100644 index 000000000000..1383a03f4647 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/step_scripted/Steps.py @@ -0,0 +1,37 @@ +import lldb + +class StepWithChild: +    def __init__(self, thread_plan): +        self.thread_plan = thread_plan +        self.child_thread_plan = self.queue_child_thread_plan() + +    def explains_stop(self, event): +        return False + +    def should_stop(self, event): +        if not self.child_thread_plan.IsPlanComplete(): +            return False + +        self.thread_plan.SetPlanComplete(True) + +        return True + +    def should_step(self): +        return False + +    def queue_child_thread_plan(self): +        return None + +class StepOut(StepWithChild): +    def __init__(self, thread_plan, dict): +        StepWithChild.__init__(self, thread_plan) + +    def queue_child_thread_plan(self): +        return self.thread_plan.QueueThreadPlanForStepOut(0) + +class StepScripted(StepWithChild): +    def __init__(self, thread_plan, dict): +        StepWithChild.__init__(self, thread_plan) + +    def queue_child_thread_plan(self): +        return self.thread_plan.QueueThreadPlanForStepScripted("Steps.StepOut") diff --git a/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py b/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py new file mode 100644 index 000000000000..a111ede6739c --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/step_scripted/TestStepScripted.py @@ -0,0 +1,41 @@ +""" +Tests stepping with scripted thread plans. +""" + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class StepScriptedTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    NO_DEBUG_INFO_TESTCASE = True + +    def test_standard_step_out(self): +        """Tests stepping with the scripted thread plan laying over a standard thread plan for stepping out.""" +        self.build() +        self.main_source_file = lldb.SBFileSpec("main.c") +        self.step_out_with_scripted_plan("Steps.StepOut") + +    def test_scripted_step_out(self): +        """Tests stepping with the scripted thread plan laying over an another scripted thread plan for stepping out.""" +        self.build() +        self.main_source_file = lldb.SBFileSpec("main.c") +        self.step_out_with_scripted_plan("Steps.StepScripted") + +    def setUp(self): +        TestBase.setUp(self) +        self.runCmd("command script import Steps.py") + +    def step_out_with_scripted_plan(self, name): +        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) + +        frame = thread.GetFrameAtIndex(0) +        self.assertEqual("foo", frame.GetFunctionName()) + +        err = thread.StepUsingScriptedThreadPlan(name) +        self.assertTrue(err.Success(), err.GetCString()) + +        frame = thread.GetFrameAtIndex(0) +        self.assertEqual("main", frame.GetFunctionName()) diff --git a/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c b/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c new file mode 100644 index 000000000000..88b3c17125db --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/step_scripted/main.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +void foo() { +  printf("Set a breakpoint here.\n"); +} + +int main() { +  foo(); +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py deleted file mode 100644 index 767b368cc7dc..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookCmd.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -Test lldb target stop-hook command. -""" - -from __future__ import print_function - - -import os -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class StopHookCmdTestCase(TestBase): - -    mydir = TestBase.compute_mydir(__file__) - -    def setUp(self): -        # Call super's setUp(). -        TestBase.setUp(self) -        # Find the line numbers inside main.cpp. -        self.begl = line_number( -            'main.cpp', -            '// Set breakpoint here to test target stop-hook.') -        self.endl = line_number( -            'main.cpp', -            '// End of the line range for which stop-hook is to be run.') -        self.line = line_number( -            'main.cpp', -            '// Another breakpoint which is outside of the stop-hook range.') - -    @no_debug_info_test -    def test_not_crashing_if_no_target(self): -        """target stop-hook list should not crash if no target has been set.""" -        self.runCmd("target stop-hook list", check=False) - -    def test(self): -        """Test a sequence of target stop-hook commands.""" -        self.build() -        exe = self.getBuildArtifact("a.out") -        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) - -        lldbutil.run_break_set_by_file_and_line( -            self, "main.cpp", self.begl, num_expected_locations=1, loc_exact=True) - -        lldbutil.run_break_set_by_file_and_line( -            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) - -        self.runCmd( -            "target stop-hook add -f main.cpp -l %d -e %d -o 'expr ptr'" % -            (self.begl, self.endl)) - -        self.expect('target stop-hook list', 'Stop Hook added successfully', -                    substrs=['State: enabled', -                             'expr ptr']) - -        self.runCmd('target stop-hook disable') - -        self.expect('target stop-hook list', 'Stop Hook disabled successfully', -                    substrs=['State: disabled', -                             'expr ptr']) - -        self.runCmd('target stop-hook enable') - -        self.expect('target stop-hook list', 'Stop Hook enabled successfully', -                    substrs=['State: enabled', -                             'expr ptr']) - -        self.runCmd("settings set auto-confirm true") -        self.addTearDownHook( -            lambda: self.runCmd("settings clear auto-confirm")) - -        self.runCmd('target stop-hook delete') - -        self.expect('target stop-hook list', 'Stop Hook deleted successfully', -                    substrs=['No stop hooks.']) diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py deleted file mode 100644 index b76d98a333c2..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/stop-hook/TestStopHookMechanism.py +++ /dev/null @@ -1,128 +0,0 @@ -""" -Test lldb target stop-hook mechanism to see whether it fires off correctly . -""" - -from __future__ import print_function - - -import os -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import configuration -from lldbsuite.test import lldbutil - - -class StopHookMechanismTestCase(TestBase): - -    mydir = TestBase.compute_mydir(__file__) - -    def setUp(self): -        # Call super's setUp(). -        TestBase.setUp(self) -        # Find the line numbers inside main.cpp. -        self.begl = line_number( -            'main.cpp', -            '// Set breakpoint here to test target stop-hook.') -        self.endl = line_number( -            'main.cpp', -            '// End of the line range for which stop-hook is to be run.') -        self.correct_step_line = line_number( -            'main.cpp', '// We should stop here after stepping.') -        self.line = line_number( -            'main.cpp', -            '// Another breakpoint which is outside of the stop-hook range.') - -    @skipIfFreeBSD  # llvm.org/pr15037 -    # stop-hooks sometimes fail to fire on Linux -    @expectedFlakeyLinux('llvm.org/pr15037') -    @expectedFailureAll( -        hostoslist=["windows"], -        bugnumber="llvm.org/pr22274: need a pexpect replacement for windows") -    @skipIf(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'armv7k'])  # <rdar://problem/34582291> problem with armv7 and step-over and stop-hook firing on ios etc systems -    def test(self): -        """Test the stop-hook mechanism.""" -        self.build() - -        import pexpect -        exe = self.getBuildArtifact("a.out") -        prompt = "(lldb) " -        add_prompt = "Enter your stop hook command(s).  Type 'DONE' to end." -        add_prompt1 = "> " - -        # So that the child gets torn down after the test. -        self.child = pexpect.spawn('%s %s' % -                                   (lldbtest_config.lldbExec, self.lldbOption)) -        child = self.child -        # Turn on logging for what the child sends back. -        if self.TraceOn(): -            child.logfile_read = sys.stdout - -        if lldb.remote_platform: -            child.expect_exact(prompt) -            child.sendline( -                'platform select %s' % -                lldb.remote_platform.GetName()) -            child.expect_exact(prompt) -            child.sendline( -                'platform connect %s' % -                configuration.lldb_platform_url) -            child.expect_exact(prompt) -            child.sendline( -                'platform settings -w %s' % -                configuration.lldb_platform_working_dir) - -        child.expect_exact(prompt) -        child.sendline('target create %s' % exe) - -        # Set the breakpoint, followed by the target stop-hook commands. -        child.expect_exact(prompt) -        child.sendline('breakpoint set -f main.cpp -l %d' % self.begl) -        child.expect_exact(prompt) -        child.sendline('breakpoint set -f main.cpp -l %d' % self.line) -        child.expect_exact(prompt) -        child.sendline( -            'target stop-hook add -f main.cpp -l %d -e %d' % -            (self.begl, self.endl)) -        child.expect_exact(add_prompt) -        child.expect_exact(add_prompt1) -        child.sendline('expr ptr') -        child.expect_exact(add_prompt1) -        child.sendline('DONE') -        child.expect_exact(prompt) -        child.sendline('target stop-hook list') - -        # Now run the program, expect to stop at the first breakpoint which is -        # within the stop-hook range. -        child.expect_exact(prompt) -        child.sendline('run') -        # Make sure we see the stop hook text from the stop of the process from -        # the run hitting the first breakpoint -        child.expect_exact('(void *) $') -        child.expect_exact(prompt) -        child.sendline('thread step-over') -        # Expecting to find the output emitted by the firing of our stop hook. -        child.expect_exact('(void *) $') -        # This is orthogonal to the main stop hook test, but this example shows a bug in -        # CLANG where the line table entry for the "return -1" actually includes some code -        # from the other branch of the if/else, so we incorrectly stop at the "return -1" line. -        # I fixed that in lldb and I'm sticking in a test here because I don't want to have to -        # make up a whole nother test case for it. -        child.sendline('frame info') -        at_line = 'at main.cpp:%d' % (self.correct_step_line) -        print('expecting "%s"' % at_line) -        child.expect_exact(at_line) - -        # Now continue the inferior, we'll stop at another breakpoint which is -        # outside the stop-hook range. -        child.sendline('process continue') -        child.expect_exact( -            '// Another breakpoint which is outside of the stop-hook range.') -        # self.DebugPExpect(child) -        child.sendline('thread step-over') -        child.expect_exact( -            '// Another breakpoint which is outside of the stop-hook range.') -        # self.DebugPExpect(child) -        # Verify that the 'Stop Hooks' mechanism is NOT BEING fired off. -        self.expect(child.before, exe=False, matching=False, -                    substrs=['(void *) $']) diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/main.cpp b/packages/Python/lldbsuite/test/functionalities/stop-hook/main.cpp deleted file mode 100644 index c10c1e5ef0d2..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/stop-hook/main.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//===-- 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> -#include <stdlib.h> - -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); - -    return val; -} - -int b(int val) -{ -    int rc = c(val); -    void *ptr = malloc(1024); -    if (!ptr)  // Set breakpoint here to test target stop-hook. -        return -1; -    else -        printf("ptr=%p\n", ptr); // We should stop here after stepping. -    return rc; // End of the line range for which stop-hook is to be run. -} - -int c(int val) -{ -    return val + 3; -} - -int main (int argc, char const *argv[]) -{ -    int A1 = a(1); -    printf("a(1) returns %d\n", A1); -     -    int C2 = c(2); // Another breakpoint which is outside of the stop-hook range. -    printf("c(2) returns %d\n", C2); -     -    int A3 = a(3); -    printf("a(3) returns %d\n", A3); -     -    return 0; -} diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py deleted file mode 100644 index 88267b60b978..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py +++ /dev/null @@ -1,100 +0,0 @@ -""" -Test that lldb stop-hook works for multiple threads. -""" - -from __future__ import print_function - - -import os -import time -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import configuration -from lldbsuite.test import lldbutil - - -class StopHookForMultipleThreadsTestCase(TestBase): - -    mydir = TestBase.compute_mydir(__file__) - -    def setUp(self): -        # Call super's setUp(). -        TestBase.setUp(self) -        # Our simple source filename. -        self.source = 'main.cpp' -        # Find the line number to break inside main(). -        self.first_stop = line_number( -            self.source, '// Set break point at this line, and add a stop-hook.') -        self.thread_function = line_number( -            self.source, -            '// Break here to test that the stop-hook mechanism works for multiple threads.') -        # Build dictionary to have unique executable names for each test -        # method. -        self.exe_name = self.testMethodName -        self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name} - -    @expectedFlakeyFreeBSD("llvm.org/pr15037") -    # stop hooks sometimes fail to fire on Linux -    @expectedFlakeyLinux("llvm.org/pr15037") -    @expectedFailureAll( -        hostoslist=["windows"], -        bugnumber="llvm.org/pr22274: need a pexpect replacement for windows") -    def test_stop_hook_multiple_threads(self): -        """Test that lldb stop-hook works for multiple threads.""" -        self.build(dictionary=self.d) -        self.setTearDownCleanup(dictionary=self.d) - -        import pexpect -        exe = self.getBuildArtifact(self.exe_name) -        prompt = "(lldb) " - -        # So that the child gets torn down after the test. -        self.child = pexpect.spawn('%s %s' % -                                   (lldbtest_config.lldbExec, self.lldbOption)) -        child = self.child -        # Turn on logging for what the child sends back. -        if self.TraceOn(): -            child.logfile_read = sys.stdout - -        if lldb.remote_platform: -            child.expect_exact(prompt) -            child.sendline( -                'platform select %s' % -                lldb.remote_platform.GetName()) -            child.expect_exact(prompt) -            child.sendline( -                'platform connect %s' % -                configuration.lldb_platform_url) -            child.expect_exact(prompt) -            child.sendline( -                'platform settings -w %s' % -                configuration.lldb_platform_working_dir) - -        child.expect_exact(prompt) -        child.sendline('target create %s' % exe) - -        # Set the breakpoint, followed by the target stop-hook commands. -        child.expect_exact(prompt) -        child.sendline('breakpoint set -f main.cpp -l %d' % self.first_stop) -        child.expect_exact(prompt) -        child.sendline( -            'breakpoint set -f main.cpp -l %d' % -            self.thread_function) -        child.expect_exact(prompt) - -        # Now run the program, expect to stop at the first breakpoint which is -        # within the stop-hook range. -        child.sendline('run') -        # 'Process 2415 launched', 'Process 2415 stopped' -        child.expect_exact("Process") -        child.expect_exact(prompt) -        child.sendline( -            'target stop-hook add -o "frame variable --show-globals g_val"') -        child.expect_exact("Stop hook")  # 'Stop hook #1 added.' -        child.expect_exact(prompt) - -        # Continue and expect to find the output emitted by the firing of our -        # stop hook. -        child.sendline('continue') -        child.expect_exact('(uint32_t) ::g_val = ') diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/main.cpp b/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/main.cpp deleted file mode 100644 index e193ae18e2c1..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/main.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===-- main.cpp ------------------------------------------------*- C++ -*-===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <chrono> -#include <cstdio> -#include <mutex> -#include <random> -#include <thread> - -std::default_random_engine g_random_engine{std::random_device{}()}; -std::uniform_int_distribution<> g_distribution{0, 3000000}; - -uint32_t g_val = 0; - -uint32_t -access_pool (bool flag = false) -{ -    static std::mutex g_access_mutex; -    if (!flag) -        g_access_mutex.lock(); - -    uint32_t old_val = g_val; -    if (flag) -        g_val = old_val + 1; - -    if (!flag) -        g_access_mutex.unlock(); -    return g_val; -} - -void -thread_func (uint32_t thread_index) -{ -    // Break here to test that the stop-hook mechanism works for multiple threads. -    printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index); - -    uint32_t count = 0; -    uint32_t val; -    while (count++ < 15) -    { -        // random micro second sleep from zero to 3 seconds -        int usec = g_distribution(g_random_engine); -        printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec); -        std::this_thread::sleep_for(std::chrono::microseconds{usec}); - -        if (count < 7) -            val = access_pool (); -        else -            val = access_pool (true); - -        printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count); -    } -    printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index); -} - - -int main (int argc, char const *argv[]) -{ -    std::thread threads[3]; - -    printf ("Before turning all three threads loose...\n"); // Set break point at this line, and add a stop-hook. -    // Create 3 threads -    for (auto &thread : threads) -        thread = std::thread{thread_func, std::distance(threads, &thread)}; - -    // Join all of our threads -    for (auto &thread : threads) -        thread.join(); - -    return 0; -} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/TestAmbiguousTailCallSeq1.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/TestAmbiguousTailCallSeq1.py new file mode 100644 index 000000000000..aec4d503fd73 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/TestAmbiguousTailCallSeq1.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), +        [decorators.skipUnlessHasCallSiteInfo]) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/main.cpp new file mode 100644 index 000000000000..48190184be10 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq1/main.cpp @@ -0,0 +1,33 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink() { +  x++; //% self.filecheck("bt", "main.cpp") +  // CHECK-NOT: func{{[23]}}_amb +} + +void __attribute__((noinline)) func3_amb() { sink(); /* tail */ } + +void __attribute__((noinline)) func2_amb() { sink(); /* tail */ } + +void __attribute__((noinline)) func1() { +  if (x > 0) +    func2_amb(); /* tail */ +  else +    func3_amb(); /* tail */ +} + +int __attribute__((disable_tail_calls)) main(int argc, char **) { +  // The sequences `main -> func1 -> f{2,3}_amb -> sink` are both plausible. Test +  // that lldb doesn't attempt to guess which one occurred. +  func1(); +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/TestAmbiguousTailCallSeq2.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/TestAmbiguousTailCallSeq2.py new file mode 100644 index 000000000000..aec4d503fd73 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/TestAmbiguousTailCallSeq2.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), +        [decorators.skipUnlessHasCallSiteInfo]) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/main.cpp new file mode 100644 index 000000000000..1651db2ea4a1 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/ambiguous_tail_call_seq2/main.cpp @@ -0,0 +1,38 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink() { +  x++; //% self.filecheck("bt", "main.cpp") +  // CHECK-NOT: func{{[23]}} +} + +void func2(); + +void __attribute__((noinline)) func1() { +  if (x < 1) +    func2(); +  else +    sink(); +} + +void __attribute__((noinline)) func2() { +  if (x < 1) +    sink(); +  else +    func1(); +} + +int main() { +  // Tail recursion creates ambiguous execution histories. +  x = 0; +  func1(); +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/TestDisambiguateCallSite.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/TestDisambiguateCallSite.py new file mode 100644 index 000000000000..aec4d503fd73 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/TestDisambiguateCallSite.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), +        [decorators.skipUnlessHasCallSiteInfo]) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/main.cpp new file mode 100644 index 000000000000..d3aef19f7a4f --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_call_site/main.cpp @@ -0,0 +1,32 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink() { +  x++; //% self.filecheck("bt", "main.cpp", "-implicit-check-not=artificial") +  // CHECK: frame #0: 0x{{[0-9a-f]+}} a.out`sink() at main.cpp:[[@LINE-1]]:4 [opt] +  // CHECK-NEXT: func2{{.*}} [opt] [artificial] +  // CHECK-NEXT: main{{.*}} [opt] +} + +void __attribute__((noinline)) func2() { +  sink(); /* tail */ +} + +void __attribute__((noinline)) func1() { sink(); /* tail */ } + +int __attribute__((disable_tail_calls)) main(int argc, char **) { +  // The sequences `main -> f{1,2} -> sink` are both plausible. Test that +  // return-pc call site info allows lldb to pick the correct sequence. +  func2(); +  if (argc == 100) +    func1(); +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/TestDisambiguatePathsToCommonSink.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/TestDisambiguatePathsToCommonSink.py new file mode 100644 index 000000000000..aec4d503fd73 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/TestDisambiguatePathsToCommonSink.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), +        [decorators.skipUnlessHasCallSiteInfo]) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/main.cpp new file mode 100644 index 000000000000..5189218c4ef4 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_paths_to_common_sink/main.cpp @@ -0,0 +1,38 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink2() { +  x++; //% self.filecheck("bt", "main.cpp", "-check-prefix=FROM-FUNC1") +  // FROM-FUNC1: frame #0: 0x{{[0-9a-f]+}} a.out`sink{{.*}} at main.cpp:[[@LINE-1]]:{{.*}} [opt] +  // FROM-FUNC1-NEXT: sink({{.*}} [opt] +  // FROM-FUNC1-NEXT: func1{{.*}} [opt] [artificial] +  // FROM-FUNC1-NEXT: main{{.*}} [opt] +} + +void __attribute__((noinline)) sink(bool called_from_main) { +  if (called_from_main) { +    x++; //% self.filecheck("bt", "main.cpp", "-check-prefix=FROM-MAIN") +    // FROM-MAIN: frame #0: 0x{{[0-9a-f]+}} a.out`sink{{.*}} at main.cpp:[[@LINE-1]]:{{.*}} [opt] +    // FROM-MAIN-NEXT: main{{.*}} [opt] +  } else { +    sink2(); +  } +} + +void __attribute__((noinline)) func1() { sink(false); /* tail */ } + +int __attribute__((disable_tail_calls)) main(int argc, char **) { +  // When func1 tail-calls sink, make sure that the former appears in the +  // backtrace. +  sink(true); +  func1(); +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/TestDisambiguateTailCallSeq.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/TestDisambiguateTailCallSeq.py new file mode 100644 index 000000000000..aec4d503fd73 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/TestDisambiguateTailCallSeq.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), +        [decorators.skipUnlessHasCallSiteInfo]) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/main.cpp new file mode 100644 index 000000000000..3c723b8a3ee3 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/disambiguate_tail_call_seq/main.cpp @@ -0,0 +1,31 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink() { +  x++; //% self.filecheck("bt", "main.cpp", "-implicit-check-not=artificial") +  // CHECK: frame #0: 0x{{[0-9a-f]+}} a.out`sink() at main.cpp:[[@LINE-1]]:4 [opt] +  // CHECK-NEXT: func3{{.*}} [opt] [artificial] +  // CHECK-NEXT: func1{{.*}} [opt] [artificial] +  // CHECK-NEXT: main{{.*}} [opt] +} + +void __attribute__((noinline)) func3() { sink(); /* tail */ } + +void __attribute__((noinline)) func2() { sink(); /* tail */ } + +void __attribute__((noinline)) func1() { func3(); /* tail */ } + +int __attribute__((disable_tail_calls)) main(int argc, char **) { +  // The sequences `main -> func1 -> f{2,3} -> sink` are both plausible. Test +  // that lldb picks the latter sequence. +  func1(); +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/TestInliningAndTailCalls.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/TestInliningAndTailCalls.py new file mode 100644 index 000000000000..aec4d503fd73 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/TestInliningAndTailCalls.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), +        [decorators.skipUnlessHasCallSiteInfo]) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/main.cpp new file mode 100644 index 000000000000..e4504ad151fa --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/inlining_and_tail_calls/main.cpp @@ -0,0 +1,50 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) tail_call_sink() { +  x++; //% self.filecheck("bt", "main.cpp", "-check-prefix=TAIL-CALL-SINK") +  // TAIL-CALL-SINK: frame #0: 0x{{[0-9a-f]+}} a.out`tail_call_sink() at main.cpp:[[@LINE-1]]:4 [opt] +  // TAIL-CALL-SINK-NEXT: func3{{.*}} [opt] [artificial] +  // TAIL-CALL-SINK-NEXT: main{{.*}} [opt] + +  // TODO: The backtrace should include inlinable_function_which_tail_calls. +} + +void __attribute__((always_inline)) inlinable_function_which_tail_calls() { +  tail_call_sink(); +} + +void __attribute__((noinline)) func3() { +  inlinable_function_which_tail_calls(); +} + +void __attribute__((always_inline)) inline_sink() { +  x++; //% self.filecheck("bt", "main.cpp", "-check-prefix=INLINE-SINK") +  // INLINE-SINK: frame #0: 0x{{[0-9a-f]+}} a.out`func2() [inlined] inline_sink() at main.cpp:[[@LINE-1]]:4 [opt] +  // INLINE-SINK-NEXT: func2{{.*}} [opt] +  // INLINE-SINK-NEXT: func1{{.*}} [opt] [artificial] +  // INLINE-SINK-NEXT: main{{.*}} [opt] +} + +void __attribute__((noinline)) func2() { inline_sink(); /* inlined */ } + +void __attribute__((noinline)) func1() { func2(); /* tail */ } + +int __attribute__((disable_tail_calls)) main() { +  // First, call a function that tail-calls a function, which itself inlines +  // a third function. +  func1(); + +  // Next, call a function which contains an inlined tail-call. +  func3(); + +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/TestTailCallFrameSBAPI.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/TestTailCallFrameSBAPI.py new file mode 100644 index 000000000000..038a0c45bf42 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/TestTailCallFrameSBAPI.py @@ -0,0 +1,73 @@ +""" +Test SB API support for identifying artificial (tail call) frames. +""" + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * + +class TestTailCallFrameSBAPI(TestBase): +    mydir = TestBase.compute_mydir(__file__) + +    # If your test case doesn't stress debug info, the +    # set this to true.  That way it won't be run once for +    # each debug info format. +    NO_DEBUG_INFO_TESTCASE = True + +    @skipIf(compiler="clang", compiler_version=['<', '7.0']) +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr26265") +    def test_tail_call_frame_sbapi(self): +        self.build() +        self.do_test() + +    def setUp(self): +        # Call super's setUp(). +        TestBase.setUp(self) + +    def do_test(self): +        exe = self.getBuildArtifact("a.out") + +        # Create a target by the debugger. +        target = self.dbg.CreateTarget(exe) +        self.assertTrue(target, VALID_TARGET) + +        breakpoint = target.BreakpointCreateBySourceRegex("break here", +                lldb.SBFileSpec("main.cpp")) +        self.assertTrue(breakpoint and +                        breakpoint.GetNumLocations() == 1, +                        VALID_BREAKPOINT) + +        error = lldb.SBError() +        launch_info = lldb.SBLaunchInfo(None) +        process = target.Launch(launch_info, error) +        self.assertTrue(process, PROCESS_IS_VALID) + +        # Did we hit our breakpoint? +        threads = lldbutil.get_threads_stopped_at_breakpoint(process, +                breakpoint) +        self.assertEqual( +            len(threads), 1, +            "There should be a thread stopped at our breakpoint") + +        self.assertEqual(breakpoint.GetHitCount(), 1) + +        thread = threads[0] + +        # Here's what we expect to see in the backtrace: +        #   frame #0: ... a.out`sink() at main.cpp:13:4 [opt] +        #   frame #1: ... a.out`func3() at main.cpp:14:1 [opt] [artificial] +        #   frame #2: ... a.out`func2() at main.cpp:18:62 [opt] +        #   frame #3: ... a.out`func1() at main.cpp:18:85 [opt] [artificial] +        #   frame #4: ... a.out`main at main.cpp:23:3 [opt] +        names = ["sink", "func3", "func2", "func1", "main"] +        artificiality = [False, True, False, True, False] +        for idx, (name, is_artificial) in enumerate(zip(names, artificiality)): +            frame = thread.GetFrameAtIndex(idx) + +            # Use a relaxed substring check because function dislpay names are +            # platform-dependent. E.g we see "void sink(void)" on Windows, but +            # "sink()" on Darwin. This seems like a bug -- just work around it +            # for now. +            self.assertTrue(name in frame.GetDisplayFunctionName()) +            self.assertEqual(frame.IsArtificial(), is_artificial) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/main.cpp new file mode 100644 index 000000000000..f9e84da51739 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/sbapi_support/main.cpp @@ -0,0 +1,25 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink() { +  x++; /* break here */ +} + +void __attribute__((noinline)) func3() { sink(); /* tail */ } + +void __attribute__((disable_tail_calls, noinline)) func2() { func3(); /* regular */ } + +void __attribute__((noinline)) func1() { func2(); /* tail */ } + +int __attribute__((disable_tail_calls)) main() { +  func1(); /* regular */ +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/TestArtificialFrameStepOutMessage.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/TestArtificialFrameStepOutMessage.py new file mode 100644 index 000000000000..aec4d503fd73 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/TestArtificialFrameStepOutMessage.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), +        [decorators.skipUnlessHasCallSiteInfo]) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/main.cpp new file mode 100644 index 000000000000..f2f11365df7a --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_message/main.cpp @@ -0,0 +1,28 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink() { +  x++; //% self.filecheck("finish", "main.cpp", "-implicit-check-not=artificial") +  // CHECK: stop reason = step out +  // CHECK-NEXT: Stepped out past: frame #1: 0x{{[0-9a-f]+}} a.out`func3{{.*}} [opt] [artificial] +  // CHECK: frame #0: 0x{{[0-9a-f]+}} a.out`func2{{.*}} [opt] +} + +void __attribute__((noinline)) func3() { sink(); /* tail */ } + +void __attribute__((disable_tail_calls, noinline)) func2() { func3(); /* regular */ } + +void __attribute__((noinline)) func1() { func2(); /* tail */ } + +int __attribute__((disable_tail_calls)) main() { +  func1(); /* regular */ +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/TestSteppingOutWithArtificialFrames.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/TestSteppingOutWithArtificialFrames.py new file mode 100644 index 000000000000..2b432e56a740 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/TestSteppingOutWithArtificialFrames.py @@ -0,0 +1,95 @@ +""" +Test SB API support for identifying artificial (tail call) frames. +""" + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * + +class TestArtificialFrameThreadStepOut1(TestBase): +    mydir = TestBase.compute_mydir(__file__) + +    # If your test case doesn't stress debug info, the +    # set this to true.  That way it won't be run once for +    # each debug info format. +    NO_DEBUG_INFO_TESTCASE = True + +    def prepare_thread(self): +        exe = self.getBuildArtifact("a.out") + +        # Create a target by the debugger. +        target = self.dbg.CreateTarget(exe) +        self.assertTrue(target, VALID_TARGET) + +        breakpoint = target.BreakpointCreateBySourceRegex("break here", +                lldb.SBFileSpec("main.cpp")) +        self.assertTrue(breakpoint and +                        breakpoint.GetNumLocations() == 1, +                        VALID_BREAKPOINT) + +        error = lldb.SBError() +        launch_info = lldb.SBLaunchInfo(None) +        process = target.Launch(launch_info, error) +        self.assertTrue(process, PROCESS_IS_VALID) + +        # Did we hit our breakpoint? +        threads = lldbutil.get_threads_stopped_at_breakpoint(process, +                breakpoint) +        self.assertEqual( +            len(threads), 1, +            "There should be a thread stopped at our breakpoint") + +        self.assertEqual(breakpoint.GetHitCount(), 1) + +        thread = threads[0] + +        # Here's what we expect to see in the backtrace: +        #   frame #0: ... a.out`sink() at main.cpp:13:4 [opt] +        #   frame #1: ... a.out`func3() at main.cpp:14:1 [opt] [artificial] +        #   frame #2: ... a.out`func2() at main.cpp:18:62 [opt] +        #   frame #3: ... a.out`func1() at main.cpp:18:85 [opt] [artificial] +        #   frame #4: ... a.out`main at main.cpp:23:3 [opt] +        return thread + +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr26265") +    def test_stepping_out_past_artificial_frame(self): +        self.build() +        thread = self.prepare_thread() + +        # Frame #0's ancestor is artificial. Stepping out should move to +        # frame #2, because we behave as-if artificial frames were not present. +        thread.StepOut() +        frame2 = thread.GetSelectedFrame() +        self.assertEqual(frame2.GetDisplayFunctionName(), "func2()") +        self.assertFalse(frame2.IsArtificial()) + +        # Ditto: stepping out of frame #2 should move to frame #4. +        thread.StepOut() +        frame4 = thread.GetSelectedFrame() +        self.assertEqual(frame4.GetDisplayFunctionName(), "main") +        self.assertFalse(frame2.IsArtificial()) + +    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr26265") +    def test_return_past_artificial_frame(self): +        self.build() +        thread = self.prepare_thread() + +        value = lldb.SBValue() + +        # Frame #0's ancestor is artificial. Returning from frame #0 should move +        # to frame #2. +        thread.ReturnFromFrame(thread.GetSelectedFrame(), value) +        frame2 = thread.GetSelectedFrame() +        self.assertEqual(frame2.GetDisplayFunctionName(), "func2()") +        self.assertFalse(frame2.IsArtificial()) + +        # Ditto: stepping out of frame #2 should move to frame #4. +        thread.ReturnFromFrame(thread.GetSelectedFrame(), value) +        frame4 = thread.GetSelectedFrame() +        self.assertEqual(frame4.GetDisplayFunctionName(), "main") +        self.assertFalse(frame2.IsArtificial()) + +    def setUp(self): +        # Call super's setUp(). +        TestBase.setUp(self) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/main.cpp new file mode 100644 index 000000000000..f7a81873906e --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/thread_step_out_or_return/main.cpp @@ -0,0 +1,25 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink() { +  x++; // break here +} + +void __attribute__((noinline)) func3() { sink(); /* tail */ } + +void __attribute__((disable_tail_calls, noinline)) func2() { func3(); /* regular */ } + +void __attribute__((noinline)) func1() { func2(); /* tail */ } + +int __attribute__((disable_tail_calls)) main() { +  func1(); /* regular */ +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/Makefile b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/Makefile new file mode 100644 index 000000000000..15bc2e7f415b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/Makefile @@ -0,0 +1,4 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp +include $(LEVEL)/Makefile.rules +CXXFLAGS += -g -O1 -glldb diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/TestUnambiguousTailCalls.py b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/TestUnambiguousTailCalls.py new file mode 100644 index 000000000000..aec4d503fd73 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/TestUnambiguousTailCalls.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), +        [decorators.skipUnlessHasCallSiteInfo]) diff --git a/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/main.cpp b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/main.cpp new file mode 100644 index 000000000000..c180d45b9de6 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/tail_call_frames/unambiguous_sequence/main.cpp @@ -0,0 +1,30 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +volatile int x; + +void __attribute__((noinline)) sink() { +  x++; //% self.filecheck("bt", "main.cpp", "-implicit-check-not=artificial") +  // CHECK: frame #0: 0x{{[0-9a-f]+}} a.out`sink() at main.cpp:[[@LINE-1]]:4 [opt] +  // CHECK-NEXT: frame #1: 0x{{[0-9a-f]+}} a.out`func3{{.*}} [opt] [artificial] +  // CHECK-NEXT: frame #2: 0x{{[0-9a-f]+}} a.out`func2{{.*}} [opt] +  // CHECK-NEXT: frame #3: 0x{{[0-9a-f]+}} a.out`func1{{.*}} [opt] [artificial] +  // CHECK-NEXT: frame #4: 0x{{[0-9a-f]+}} a.out`main{{.*}} [opt] +} + +void __attribute__((noinline)) func3() { sink(); /* tail */ } + +void __attribute__((disable_tail_calls, noinline)) func2() { func3(); /* regular */ } + +void __attribute__((noinline)) func1() { func2(); /* tail */ } + +int __attribute__((disable_tail_calls)) main() { +  func1(); /* regular */ +  return 0; +} diff --git a/packages/Python/lldbsuite/test/functionalities/target_create_deps/Makefile b/packages/Python/lldbsuite/test/functionalities/target_create_deps/Makefile new file mode 100644 index 000000000000..15cb0b64f218 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_create_deps/Makefile @@ -0,0 +1,16 @@ +LEVEL := ../../make + +LIB_PREFIX := load_ + +LD_EXTRAS := -L. -l$(LIB_PREFIX)a +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules + +a.out: lib_a + +lib_%: +	$(MAKE) VPATH=$(SRCDIR) -I $(SRCDIR) -f $(SRCDIR)/$*.mk + +clean:: +	$(MAKE) -f $(SRCDIR)/a.mk clean diff --git a/packages/Python/lldbsuite/test/functionalities/target_create_deps/TestTargetCreateDeps.py b/packages/Python/lldbsuite/test/functionalities/target_create_deps/TestTargetCreateDeps.py new file mode 100644 index 000000000000..a6c383ce3c80 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_create_deps/TestTargetCreateDeps.py @@ -0,0 +1,100 @@ +""" +Test that loading of dependents works correctly for all the potential +combinations. +""" + +from __future__ import print_function + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +@skipIfWindows # Windows deals differently with shared libs. +class TargetDependentsTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    NO_DEBUG_INFO_TESTCASE = True + +    def setUp(self): +        TestBase.setUp(self) +        self.build() + +    def has_exactly_one_image(self, matching, msg=""): +        self.expect( +            "image list", +            "image list should contain at least one image", +            substrs=['[  0]']) +        should_match = not matching +        self.expect( +            "image list", msg, matching=should_match, substrs=['[  1]']) + +    @expectedFailureAll(oslist=["linux"]) #linux does not support loading dependent files +    def test_dependents_implicit_default_exe(self): +        """Test default behavior""" +        exe = self.getBuildArtifact("a.out") +        self.runCmd("target create  " + exe, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(False) + +    @expectedFailureAll(oslist=["linux"]) #linux does not support loading dependent files +    def test_dependents_explicit_default_exe(self): +        """Test default behavior""" +        exe = self.getBuildArtifact("a.out") +        self.runCmd("target create -ddefault " + exe, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(False) + +    def test_dependents_explicit_true_exe(self): +        """Test default behavior""" +        exe = self.getBuildArtifact("a.out") +        self.runCmd("target create -dtrue " + exe, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(True) + +    @expectedFailureAll(oslist=["linux"]) #linux does not support loading dependent files +    def test_dependents_explicit_false_exe(self): +        """Test default behavior""" +        exe = self.getBuildArtifact("a.out") +        self.runCmd("target create -dfalse " + exe, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(False) + +    def test_dependents_implicit_false_exe(self): +        """Test default behavior""" +        exe = self.getBuildArtifact("a.out") +        self.runCmd("target create  -d " + exe, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(True) + +    def test_dependents_implicit_default_lib(self): +        ctx = self.platformContext +        dylibName = ctx.shlib_prefix + 'load_a.' + ctx.shlib_extension +        lib = self.getBuildArtifact(dylibName) +        self.runCmd("target create " + lib, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(True) + +    def test_dependents_explicit_default_lib(self): +        ctx = self.platformContext +        dylibName = ctx.shlib_prefix + 'load_a.' + ctx.shlib_extension +        lib = self.getBuildArtifact(dylibName) +        self.runCmd("target create -ddefault " + lib, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(True) + +    def test_dependents_explicit_true_lib(self): +        ctx = self.platformContext +        dylibName = ctx.shlib_prefix + 'load_a.' + ctx.shlib_extension +        lib = self.getBuildArtifact(dylibName) +        self.runCmd("target create -dtrue " + lib, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(True) + +    @expectedFailureAll(oslist=["linux"]) #linux does not support loading dependent files +    def test_dependents_explicit_false_lib(self): +        ctx = self.platformContext +        dylibName = ctx.shlib_prefix + 'load_a.' + ctx.shlib_extension +        lib = self.getBuildArtifact(dylibName) +        self.runCmd("target create -dfalse " + lib, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(False) + +    def test_dependents_implicit_false_lib(self): +        ctx = self.platformContext +        dylibName = ctx.shlib_prefix + 'load_a.' + ctx.shlib_extension +        lib = self.getBuildArtifact(dylibName) +        self.runCmd("target create -d " + lib, CURRENT_EXECUTABLE_SET) +        self.has_exactly_one_image(True) diff --git a/packages/Python/lldbsuite/test/functionalities/target_create_deps/a.cpp b/packages/Python/lldbsuite/test/functionalities/target_create_deps/a.cpp new file mode 100644 index 000000000000..c0dac40d0eed --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_create_deps/a.cpp @@ -0,0 +1,13 @@ +//===-- b.c -----------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int a_function () +{ +    return 500; +} diff --git a/packages/Python/lldbsuite/test/functionalities/target_create_deps/a.mk b/packages/Python/lldbsuite/test/functionalities/target_create_deps/a.mk new file mode 100644 index 000000000000..f199bfed5b0d --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_create_deps/a.mk @@ -0,0 +1,9 @@ +LEVEL := ../../make + +LIB_PREFIX := load_ + +DYLIB_NAME := $(LIB_PREFIX)a +DYLIB_CXX_SOURCES := a.cpp +DYLIB_ONLY := YES + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/target_create_deps/main.cpp b/packages/Python/lldbsuite/test/functionalities/target_create_deps/main.cpp new file mode 100644 index 000000000000..08fbb59d8a58 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_create_deps/main.cpp @@ -0,0 +1,17 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +extern int a_function (); +extern int b_function (); + +int +main (int argc, char const *argv[]) +{ +    return a_function(); +} diff --git a/packages/Python/lldbsuite/test/functionalities/target_var/Makefile b/packages/Python/lldbsuite/test/functionalities/target_var/Makefile new file mode 100644 index 000000000000..bb9cc4f2f66d --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_var/Makefile @@ -0,0 +1,10 @@ +LEVEL = ../../make + +include $(LEVEL)/Makefile.rules + +a.out: globals.ll +	$(CC) $(CFLAGS) -g -c $^ -o globals.o +	$(LD) $(LDFLAGS) -g globals.o -o $@ + +clean:: +	rm -rf globals.o a.out *.dSYM diff --git a/packages/Python/lldbsuite/test/functionalities/target_var/TestTargetVar.py b/packages/Python/lldbsuite/test/functionalities/target_var/TestTargetVar.py new file mode 100644 index 000000000000..d3afacca72f5 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_var/TestTargetVar.py @@ -0,0 +1,23 @@ +""" +Test that target var can resolve complex DWARF expressions. +""" + +import lldb +import sys +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class targetCommandTestCase(TestBase): + +    mydir = TestBase.compute_mydir(__file__) + +    @skipUnlessDarwin +    @skipIfDarwinEmbedded           # needs x86_64 +    @skipIf(debug_info="gmodules")  # not relevant +    @skipIf(compiler="clang", compiler_version=['<', '7.0']) +    def testTargetVarExpr(self): +        self.build() +        lldbutil.run_to_name_breakpoint(self, 'main') +        self.expect("target variable i", substrs=['i', '42']) diff --git a/packages/Python/lldbsuite/test/functionalities/target_var/globals.c b/packages/Python/lldbsuite/test/functionalities/target_var/globals.c new file mode 100644 index 000000000000..266192849641 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_var/globals.c @@ -0,0 +1,6 @@ +int i = 42; +int *p = &i; + +int main() { +  return *p; +} diff --git a/packages/Python/lldbsuite/test/functionalities/target_var/globals.ll b/packages/Python/lldbsuite/test/functionalities/target_var/globals.ll new file mode 100644 index 000000000000..192d4e126981 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/target_var/globals.ll @@ -0,0 +1,42 @@ +source_filename = "globals.c" +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.14.0" + +@i = global i32 42, align 4 +@p = global i32* @i, align 8, !dbg !0, !dbg !6 + +; Function Attrs: noinline nounwind optnone ssp uwtable +define i32 @main() #0 !dbg !15 { +entry: +  %retval = alloca i32, align 4 +  store i32 0, i32* %retval, align 4 +  %0 = load i32*, i32** @p, align 8, !dbg !18 +  %1 = load i32, i32* %0, align 4, !dbg !18 +  ret i32 %1, !dbg !18 +} + +attributes #0 = { noinline nounwind optnone ssp uwtable } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_deref)) +!1 = distinct !DIGlobalVariable(name: "i", scope: !2, file: !3, line: 1, type: !9, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5) +!3 = !DIFile(filename: "globals.c", directory: "/") +!4 = !{} +!5 = !{!0, !6} +!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!7 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true) +!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64) +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{i32 7, !"PIC Level", i32 2} +!14 = !{!"clang version 8.0.0 (trunk 340838) (llvm/trunk 340843)"} +!15 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 4, type: !16, isLocal: false, isDefinition: true, scopeLine: 4, isOptimized: false, unit: !2, retainedNodes: !4) +!16 = !DISubroutineType(types: !17) +!17 = !{!9} +!18 = !DILocation(line: 5, scope: !15) diff --git a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/Makefile b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile index 035413ff763d..f0bcf9752de2 100644 --- a/packages/Python/lldbsuite/test/functionalities/stop-hook/multiple_threads/Makefile +++ b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/Makefile @@ -1,6 +1,6 @@  LEVEL = ../../../make +CXXFLAGS += -std=c++11  CXX_SOURCES := main.cpp  ENABLE_THREADS := YES -  include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py new file mode 100644 index 000000000000..4e595ea4c5f6 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/TestBacktraceLimit.py @@ -0,0 +1,31 @@ +""" +Test that the target.process.thread.max-backtrace-depth setting works. +""" + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BacktraceLimitSettingTest(TestBase): + +    mydir = TestBase.compute_mydir(__file__) +    NO_DEBUG_INFO_TESTCASE = True + +    def setUp(self): +        # Call super's setUp(). +        TestBase.setUp(self) + +    def test_backtrace_depth(self): +        """Test that the max-backtrace-depth setting limits backtraces.""" +        self.build() +        self.main_source_file = lldb.SBFileSpec("main.cpp") +        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, +                "Set a breakpoint here", self.main_source_file) +        interp = self.dbg.GetCommandInterpreter() +        result = lldb.SBCommandReturnObject() +        interp.HandleCommand("settings set target.process.thread.max-backtrace-depth 30", result) +        self.assertEqual(True, result.Succeeded()) +        self.assertEqual(30, thread.GetNumFrames()) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp new file mode 100644 index 000000000000..eca1eadc8e45 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/thread/backtrace_limit/main.cpp @@ -0,0 +1,13 @@ +int bottom () {  +  return 1;  // Set a breakpoint here +}  +int foo(int in) {  +  if (in > 0) +    return foo(--in) + 5;  +  else +    return bottom(); +} +int main() +{ +   return foo(500); +} diff --git a/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py index b20b738825a2..fa96db06a59d 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/crash_during_step/TestCrashDuringStep.py @@ -20,7 +20,6 @@ class CrashDuringStepTestCase(TestBase):          TestBase.setUp(self)          self.breakpoint = line_number('main.cpp', '// Set breakpoint here') -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")      # IO error due to breakpoint at invalid address      @expectedFailureAll(triple=re.compile('^mips'))      def test_step_inst_with(self): diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py index 3f26d8c76579..2afa77d34b5e 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/create_after_attach/TestCreateAfterAttach.py @@ -23,7 +23,6 @@ class CreateAfterAttachTestCase(TestBase):      # Occasionally hangs on Windows, may be same as other issues.      @skipIfWindows      @skipIfiOSSimulator -    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], bugnumber="<rdar://problem/34538611>") # old lldb-server has race condition, launching an inferior and then launching debugserver in quick succession sometimes fails      def test_create_after_attach_with_popen(self):          """Test thread creation after process attach."""          self.build(dictionary=self.getBuildFlags(use_cpp11=False)) @@ -34,7 +33,6 @@ class CreateAfterAttachTestCase(TestBase):      @skipIfRemote      @skipIfWindows  # Windows doesn't have fork.      @skipIfiOSSimulator -    @expectedFailureAll(oslist=['ios', 'watchos', 'tvos', 'bridgeos'], bugnumber="<rdar://problem/34538611>") # old lldb-server has race condition, launching an inferior and then launching debugserver in quick succession sometimes fails      def test_create_after_attach_with_fork(self):          """Test thread creation after process attach."""          self.build(dictionary=self.getBuildFlags(use_cpp11=False)) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py index c62990ccc93a..76c2c47da2cf 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_break/TestExitDuringBreak.py @@ -23,9 +23,6 @@ class ExitDuringBreakpointTestCase(TestBase):          # Find the line number for our breakpoint.          self.breakpoint = line_number('main.cpp', '// Set breakpoint here') -    @expectedFailureAll( -        oslist=["linux"], -        bugnumber="llvm.org/pr15824 thread states not properly maintained")      def test(self):          """Test thread exit during breakpoint handling."""          self.build(dictionary=self.getBuildFlags()) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py index 0343a888a0f1..76488a7185de 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py @@ -18,6 +18,7 @@ class ExitDuringStepTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__)      @skipIfFreeBSD  # llvm.org/pr21411: test is hanging +    @skipIfWindows # This is flakey on Windows: llvm.org/pr38373      def test(self):          """Test thread exit during step handling."""          self.build(dictionary=self.getBuildFlags()) @@ -27,6 +28,7 @@ class ExitDuringStepTestCase(TestBase):              True)      @skipIfFreeBSD  # llvm.org/pr21411: test is hanging +    @skipIfWindows # This is flakey on Windows: llvm.org/pr38373      def test_step_over(self):          """Test thread exit during step-over handling."""          self.build(dictionary=self.getBuildFlags()) @@ -36,6 +38,7 @@ class ExitDuringStepTestCase(TestBase):              False)      @skipIfFreeBSD  # llvm.org/pr21411: test is hanging +    @skipIfWindows # This is flakey on Windows: llvm.org/pr38373      def test_step_in(self):          """Test thread exit during step-in handling."""          self.build(dictionary=self.getBuildFlags()) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py b/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py index 3300078e8c60..7194dafe0ac1 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/jump/TestThreadJump.py @@ -17,7 +17,6 @@ class ThreadJumpTestCase(TestBase):      mydir = TestBase.compute_mydir(__file__) -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr32343")      def test(self):          """Test thread jump handling."""          self.build(dictionary=self.getBuildFlags()) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py index cff9b5a8d5e5..3d7e26816f84 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/multi_break/TestMultipleBreakpoints.py @@ -32,9 +32,7 @@ class MultipleBreakpointTestCase(TestBase):      @expectedFailureAll(          oslist=["freebsd"],          bugnumber="llvm.org/pr18190 thread states not properly maintained") -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") +    @skipIfWindows # This is flakey on Windows: llvm.org/pr24668, llvm.org/pr38373      def test(self):          """Test simultaneous breakpoints in multiple threads."""          self.build(dictionary=self.getBuildFlags()) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py index 724b9d8be907..9aa4a831a745 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py @@ -64,7 +64,7 @@ class NumberOfThreadsTestCase(TestBase):              'Number of expected threads and actual threads do not match.')      @skipIfDarwin # rdar://33462362 -    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr37658") +    @skipIfWindows # This is flakey on Windows: llvm.org/pr37658, llvm.org/pr38373      def test_unique_stacks(self):          """Test backtrace unique with multiple threads executing the same stack."""          self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py b/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py index 0cbd94e199dc..4b1247316e18 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/state/TestThreadStates.py @@ -52,17 +52,6 @@ class ThreadStateTestCase(TestBase):          self.thread_state_after_expression_test()      # thread states not properly maintained -    @unittest2.expectedFailure("llvm.org/pr16712") -    @expectedFailureAll( -        oslist=["windows"], -        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") -    @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237> -    def test_process_interrupt(self): -        """Test process interrupt.""" -        self.build(dictionary=self.getBuildFlags(use_cpp11=False)) -        self.process_interrupt_test() - -    # thread states not properly maintained      @unittest2.expectedFailure("llvm.org/pr15824 and <rdar://problem/28557237>")      @expectedFailureAll(          oslist=["windows"], @@ -198,13 +187,19 @@ class ThreadStateTestCase(TestBase):          # Let the process run to completion          self.runCmd("process continue") -    def process_interrupt_test(self): +    @expectedFailureAll( +        oslist=["windows"], +        bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly") +    @skipIfDarwin # llvm.org/pr15824 thread states not properly maintained and <rdar://problem/28557237> +    @no_debug_info_test +    def test_process_interrupt(self):          """Test process interrupt and continue.""" +        self.build(dictionary=self.getBuildFlags(use_cpp11=False))          exe = self.getBuildArtifact("a.out")          self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)          # This should create a breakpoint in the main thread. -        lldbutil.run_break_set_by_file_and_line( +        bpno = lldbutil.run_break_set_by_file_and_line(              self, "main.cpp", self.break_1, num_expected_locations=1)          # Run the program. @@ -218,6 +213,10 @@ class ThreadStateTestCase(TestBase):              process, lldb.eStopReasonBreakpoint)          self.assertIsNotNone(thread) +        # Remove the breakpoint to avoid the single-step-over-bkpt dance in the +        # "continue" below +        self.assertTrue(target.BreakpointDelete(bpno)) +          # Continue, the inferior will go into an infinite loop waiting for          # 'g_test' to change.          self.dbg.SetAsync(True) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py b/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py index 238b18837884..e786e8d7ff1e 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py @@ -25,6 +25,7 @@ class ThreadStepOutTestCase(TestBase):      @expectedFailureAll(          oslist=["freebsd"],          bugnumber="llvm.org/pr18066 inferior does not exit") +    @skipIfWindows # This test will hang on windows llvm.org/pr21753      @expectedFailureAll(oslist=["windows"])      def test_step_single_thread(self):          """Test thread step out on one thread via command interpreter. """ @@ -39,6 +40,7 @@ class ThreadStepOutTestCase(TestBase):      @expectedFailureAll(          oslist=["freebsd"],          bugnumber="llvm.org/pr19347 2nd thread stops at breakpoint") +    @skipIfWindows # This test will hang on windows llvm.org/pr21753      @expectedFailureAll(oslist=["windows"])      @expectedFailureAll(oslist=["watchos"], archs=['armv7k'], bugnumber="rdar://problem/34674488") # stop reason is trace when it should be step-out      def test_step_all_threads(self): @@ -54,6 +56,7 @@ class ThreadStepOutTestCase(TestBase):      @expectedFailureAll(          oslist=["freebsd"],          bugnumber="llvm.org/pr19347 2nd thread stops at breakpoint") +    @skipIfWindows # This test will hang on windows llvm.org/pr21753      @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24681")      def test_python(self):          """Test thread step out on one thread via Python API (dwarf).""" diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py index 07ceb3f5f6b7..c8b6e675b8a9 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py @@ -8,6 +8,7 @@ from __future__ import print_function  import os  import time  import lldb +from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import *  import lldbsuite.test.lldbutil as lldbutil @@ -25,6 +26,7 @@ class ThreadExitTestCase(TestBase):          self.break_3 = line_number('main.cpp', '// Set third breakpoint here')          self.break_4 = line_number('main.cpp', '// Set fourth breakpoint here') +    @skipIfWindows # This is flakey on Windows: llvm.org/pr38373      def test(self):          """Test thread exit handling."""          self.build(dictionary=self.getBuildFlags()) diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_hits/TestMultipleHits.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_hits/TestMultipleHits.py index 7302f76c1fbc..a6d77924892b 100644 --- a/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_hits/TestMultipleHits.py +++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/multiple_hits/TestMultipleHits.py @@ -22,6 +22,7 @@ class MultipleHitsTestCase(TestBase):          oslist=["windows"],          bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")      @skipIf(bugnumber="llvm.org/pr30758", oslist=["linux"], archs=["arm", "aarch64", "powerpc64le"]) +    @skipIfwatchOS      def test(self):          self.build()          exe = self.getBuildArtifact("a.out")  | 
