diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:06:29 +0000 |
commit | 94994d372d014ce4c8758b9605d63fae651bd8aa (patch) | |
tree | 51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /packages/Python/lldbsuite/test/functionalities | |
parent | 39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff) |
Notes
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") |