diff options
Diffstat (limited to 'gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx')
70 files changed, 3280 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/main.c new file mode 100644 index 00000000000..41a6a46c926 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/main.c @@ -0,0 +1,8 @@ +void relative(); + +int main() +{ + relative(); + // Hello Absolute! + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/relative.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/relative.c new file mode 100644 index 00000000000..02331834cf2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/relative.c @@ -0,0 +1,5 @@ +void stop() {} +void relative() { + stop(); + // Hello Relative! +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Makefile new file mode 100644 index 00000000000..8c82c73b13f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Makefile @@ -0,0 +1,10 @@ +BOTDIR = $(BUILDDIR)/buildbot +USERDIR = $(BUILDDIR)/user +C_SOURCES = $(BOTDIR)/main.c +LD_EXTRAS = $(BOTDIR)/relative.o + +include Makefile.rules + +$(EXE): relative.o +relative.o: $(BOTDIR)/relative.c + cd $(BOTDIR) && $(CC) -c $(CFLAGS) -o $@ relative.c diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/TestDSYMSourcePathRemapping.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/TestDSYMSourcePathRemapping.py new file mode 100644 index 00000000000..0f5daf51e97 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/TestDSYMSourcePathRemapping.py @@ -0,0 +1,61 @@ +import lldb +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbtest as lldbtest +import lldbsuite.test.lldbutil as lldbutil +import os +import unittest2 + + +class TestDSYMSourcePathRemapping(lldbtest.TestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def build(self): + botdir = self.getBuildArtifact('buildbot') + userdir = self.getBuildArtifact('user') + inputs = self.getSourcePath('Inputs') + lldbutil.mkdir_p(botdir) + lldbutil.mkdir_p(userdir) + import shutil + for f in ['main.c', 'relative.c']: + shutil.copyfile(os.path.join(inputs, f), os.path.join(botdir, f)) + shutil.copyfile(os.path.join(inputs, f), os.path.join(userdir, f)) + + super(TestDSYMSourcePathRemapping, self).build() + + # Remove the build sources. + self.assertTrue(os.path.isdir(botdir)) + shutil.rmtree(botdir) + + # Create a plist. + import subprocess + dsym = self.getBuildArtifact('a.out.dSYM') + uuid = subprocess.check_output(["/usr/bin/dwarfdump", "--uuid", dsym] + ).decode("utf-8").split(" ")[1] + import re + self.assertTrue(re.match(r'[0-9a-fA-F-]+', uuid)) + plist = os.path.join(dsym, 'Contents', 'Resources', uuid + '.plist') + with open(plist, 'w') as f: + f.write('<?xml version="1.0" encoding="UTF-8"?>\n') + f.write('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n') + f.write('<plist version="1.0">\n') + f.write('<dict>\n') + f.write(' <key>DBGSourcePathRemapping</key>\n') + f.write(' <dict>\n') + f.write(' <key>' + botdir + '</key>\n') + f.write(' <string>' + userdir + '</string>\n') + f.write(' </dict>\n') + f.write('</dict>\n') + f.write('</plist>\n') + + + @skipIf(debug_info=no_match("dsym")) + def test(self): + self.build() + + target, process, _, _ = lldbutil.run_to_name_breakpoint( + self, 'main') + self.expect("source list -n main", substrs=["Hello Absolute"]) + bkpt = target.BreakpointCreateByName('relative') + lldbutil.continue_to_breakpoint(process, bkpt) + self.expect("source list -n relative", substrs=["Hello Relative"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/Makefile new file mode 100644 index 00000000000..4e1ec2202d0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/Makefile @@ -0,0 +1,14 @@ +C_SOURCES = main.c + +include Makefile.rules + +all: a.out.dSYM hide.app/Contents/a.out.dSYM + +hide.app/Contents/a.out.dSYM: + mkdir hide.app + mkdir hide.app/Contents + mv a.out.dSYM hide.app/Contents + strip -x a.out +ifneq "$(CODESIGN)" "" + $(CODESIGN) -fs - a.out +endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/TestAddDsymMidExecutionCommand.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/TestAddDsymMidExecutionCommand.py new file mode 100644 index 00000000000..df9716ff513 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/TestAddDsymMidExecutionCommand.py @@ -0,0 +1,46 @@ +"""Test that the 'add-dsym', aka 'target symbols add', succeeds in the middle of debug session.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class AddDsymMidExecutionCommandCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + self.source = 'main.c' + + @no_debug_info_test # Prevent the genaration of the dwarf version of this test + def test_add_dsym_mid_execution(self): + """Test that add-dsym mid-execution loads the symbols at the right place for a slid binary.""" + self.buildDefault(dictionary={'MAKE_DSYM':'YES'}) + exe = self.getBuildArtifact("a.out") + + self.target = self.dbg.CreateTarget(exe) + self.assertTrue(self.target, VALID_TARGET) + + main_bp = self.target.BreakpointCreateByName("main", "a.out") + self.assertTrue(main_bp, VALID_BREAKPOINT) + + self.runCmd("settings set target.disable-aslr false") + self.process = self.target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(self.process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.assertTrue(self.process.GetState() == lldb.eStateStopped, + STOPPED_DUE_TO_BREAKPOINT) + + self.runCmd("add-dsym " + + self.getBuildArtifact("hide.app/Contents/a.out.dSYM")) + + self.expect("frame select", + substrs=['a.out`main at main.c']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/main.c new file mode 100644 index 00000000000..da9e09f0738 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/add-dsym/main.c @@ -0,0 +1,7 @@ +#include <stdio.h> +static int var = 5; +int main () +{ + printf ("%p is %d\n", &var, var); // break on this line + return ++var; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/Makefile new file mode 100644 index 00000000000..b880d9e722b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/Makefile @@ -0,0 +1,20 @@ +C_SOURCES := main.c + +# Make an archive that has two object files with the same name, but +# different timestamps. Do it all in one rule so that the timestamps +# can be controlled without confusing Make. +libfoo.a: a.c sub1/a.c + $(CC) $(CFLAGS) -c $(<D)/a.c -o a.o + mkdir -p sub1 + $(CC) $(CFLAGS) -c $(<D)/sub1/a.c -o sub1/a.o + touch -t '198001010000.00' a.o + touch -t '198001010000.01' sub1/a.o + $(AR) $(ARFLAGS) $@ a.o sub1/a.o + rm a.o sub1/a.o + +include Makefile.rules + +# Needs to come after include +OBJECTS += libfoo.a +$(EXE) : libfoo.a +.DEFAULT_GOAL := $(EXE) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/TestDuplicateMembers.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/TestDuplicateMembers.py new file mode 100644 index 00000000000..3fecb3beae5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/TestDuplicateMembers.py @@ -0,0 +1,52 @@ +"""Test breaking inside functions defined within a BSD archive file libfoo.a.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BSDArchivesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24527. Makefile.rules doesn't know how to build static libs on Windows") + def test(self): + """Break inside a() and b() defined within libfoo.a.""" + self.build() + + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break on a() and b() symbols + lldbutil.run_break_set_by_symbol( + self, "a", sym_exact=True) + lldbutil.run_break_set_by_symbol( + self, "b", sym_exact=True) + + 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']) + + # Break at a(int) first. + self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(int) arg = 1']) + self.expect("frame variable __a_global", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(int) __a_global = 1']) + + # Continue the program, we should break at b(int) next. + self.runCmd("continue") + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(int) arg = 2']) + self.expect("frame variable __b_global", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(int) __b_global = 2']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/a.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/a.c new file mode 100644 index 00000000000..4d57868c320 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/a.c @@ -0,0 +1,13 @@ +//===-- a.c -----------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +int __a_global = 1; + +int a(int arg) { + int result = arg + __a_global; + return result; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/main.c new file mode 100644 index 00000000000..1525a1a5e38 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/main.c @@ -0,0 +1,16 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +extern int a(int); +extern int b(int); +int main (int argc, char const *argv[]) +{ + printf ("a(1) returns %d\n", a(1)); + printf ("b(2) returns %d\n", b(2)); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/sub1/a.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/sub1/a.c new file mode 100644 index 00000000000..e90218c9676 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/duplicate-archive-members/sub1/a.c @@ -0,0 +1,13 @@ +//===-- a.c -----------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +static int __b_global = 2; + +int b(int arg) { + int result = arg + __b_global; + return result; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/Makefile new file mode 100644 index 00000000000..68012d22f5b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/Makefile @@ -0,0 +1,20 @@ +SRCDIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/ +CC ?= clang + +ifeq "$(ARCH)" "" + ARCH = x86_64 +endif + +CFLAGS ?= -g -O0 -arch $(ARCH) + +all: TestApp.app/Contents/MacOS/TestApp + +TestApp.app/Contents/MacOS/TestApp: $(SRCDIR)/main.c + $(CC) $(CFLAGS) -o TestApp $< + rm -rf TestApp.app + cp -r $(SRCDIR)/TestApp.app . + mv TestApp TestApp.app/Contents/MacOS/TestApp + mv TestApp.dSYM TestApp.app.dSYM + +clean: + rm -rf TestApp.app/Contents/MacOS/TestApp TestApp.app.dSYM diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/Info.plist b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/Info.plist new file mode 100644 index 00000000000..a47f72bb14d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/Info.plist @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>TestApp</string> + <key>CFBundleIdentifier</key> + <string>com.lldb.TestApp</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>TestApp</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSupportedPlatforms</key> + <array> + <string>MacOSX</string> + </array> + <key>CFBundleVersion</key> + <string>1</string> + <key>LSMinimumSystemVersion</key> + <string>10.8</string> + <key>NSHumanReadableCopyright</key> + <string>Copyright © 2018 Jim Ingham. All rights reserved.</string> +</dict> +</plist> diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/MacOS/.empty b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/MacOS/.empty new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/MacOS/.empty diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/Resources/.empty b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/Resources/.empty new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestApp.app/Contents/Resources/.empty diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestFindAppInBundle.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestFindAppInBundle.py new file mode 100644 index 00000000000..99d21f02208 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestFindAppInBundle.py @@ -0,0 +1,58 @@ +""" +Make sure we can find the binary inside an app bundle. +""" + + + +import lldb +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil +import lldbsuite.test.lldbplatformutil as lldbplatformutil +from lldbsuite.test.lldbtest import * + +@decorators.skipUnlessDarwin +class FindAppInMacOSAppBundle(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + def test_find_app_in_bundle(self): + """There can be many tests in a test case - describe this test here.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + self.find_app_in_bundle_test() + + def find_app_in_bundle_test(self): + """This reads in the .app, makes sure we get the right binary and can run it.""" + + # This function starts a process, "a.out" by default, sets a source + # breakpoint, runs to it, and returns the thread, process & target. + # It optionally takes an SBLaunchOption argument if you want to pass + # arguments or environment variables. + exe = self.getBuildArtifact("TestApp.app") + error = lldb.SBError() + target = self.dbg.CreateTarget(exe, None, None, False, error) + self.assertTrue(error.Success(), "Could not create target: %s"%(error.GetCString())) + self.assertTrue(target.IsValid(), "Target: TestApp.app is not valid.") + exe_module_spec = target.GetExecutable() + self.assertTrue(exe_module_spec.GetFilename(), "TestApp") + + bkpt = target.BreakpointCreateBySourceRegex("Set a breakpoint here", self.main_source_file) + self.assertTrue(bkpt.GetNumLocations() == 1, "Couldn't set a breakpoint in the main app") + + if lldbplatformutil.getPlatform() == "macosx": + launch_info = lldb.SBLaunchInfo(None) + launch_info.SetWorkingDirectory(self.get_process_working_directory()) + + error = lldb.SBError() + process = target.Launch(launch_info, error) + + self.assertTrue(process.IsValid(), "Could not create a valid process for TestApp: %s"%(error.GetCString())) + + # Frame #0 should be at our breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint(process, bkpt) + + self.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads))) + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/main.c new file mode 100644 index 00000000000..27a0cdc01a9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/main.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int +main() +{ + printf("Set a breakpoint here.\n"); + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/Makefile new file mode 100644 index 00000000000..658c9a93870 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/Makefile @@ -0,0 +1,22 @@ +SRCDIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/ +CC ?= clang + +ifeq "$(ARCH)" "" + ARCH = x86_64 +endif + +CFLAGS ?= -g -O0 -arch $(ARCH) + +all: clean + $(CC) $(CFLAGS) -dynamiclib -o com.apple.sbd $(SRCDIR)/bundle.c + mkdir com.apple.sbd.xpc + mv com.apple.sbd com.apple.sbd.xpc/ + mkdir -p com.apple.sbd.xpc.dSYM/Contents/Resources/DWARF + mv com.apple.sbd.dSYM/Contents/Resources/DWARF/com.apple.sbd com.apple.sbd.xpc.dSYM/Contents/Resources/DWARF/ + rm -rf com.apple.sbd.dSYM + mkdir hide.app + tar cf - com.apple.sbd.xpc com.apple.sbd.xpc.dSYM | ( cd hide.app;tar xBpf -) + $(CC) $(CFLAGS) -o find-bundle-with-dots-in-fn $(SRCDIR)/main.c + +clean: + rm -rf a.out a.out.dSYM hide.app com.apple.sbd com.apple.sbd.dSYM com.apple.sbd.xpc com.apple.sbd.xpc.dSYM find-bundle-with-dots-in-fn find-bundle-with-dots-in-fn.dSYM diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/TestBundleWithDotInFilename.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/TestBundleWithDotInFilename.py new file mode 100644 index 00000000000..6b38d3c3aa7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/TestBundleWithDotInFilename.py @@ -0,0 +1,72 @@ +"""Test that a dSYM can be found when a binary is in a bundle hnd has dots in the filename.""" + + +#import unittest2 +import os.path +from time import sleep + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +exe_name = 'find-bundle-with-dots-in-fn' # must match Makefile + +class BundleWithDotInFilenameTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfRemote + @skipUnlessDarwin + # This test is explicitly a dSYM test, it doesn't need to run for any other config, but + # the following doesn't work, fixme. + # @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM") + + def setUp(self): + TestBase.setUp(self) + self.source = 'main.c' + + def tearDown(self): + # Destroy process before TestBase.tearDown() + self.dbg.GetSelectedTarget().GetProcess().Destroy() + + # Call super's tearDown(). + TestBase.tearDown(self) + + def test_attach_and_check_dsyms(self): + """Test attach to binary, see if the bundle dSYM is found""" + exe = self.getBuildArtifact(exe_name) + self.build() + os.chdir(self.getBuildDir()); + popen = self.spawnSubprocess(exe) + self.addTearDownHook(self.cleanupSubprocesses) + + # Give the inferior time to start up, dlopen a bundle, remove the bundle it linked in + sleep(5) + + # Since the library that was dlopen()'ed is now removed, lldb will need to find the + # binary & dSYM via target.exec-search-paths + settings_str = "settings set target.exec-search-paths " + self.get_process_working_directory() + "/hide.app" + self.runCmd(settings_str) + + self.runCmd("process attach -p " + str(popen.pid)) + + target = self.dbg.GetSelectedTarget() + self.assertTrue(target.IsValid(), 'Should have a valid Target after attaching to process') + + setup_complete = target.FindFirstGlobalVariable("setup_is_complete") + self.assertTrue(setup_complete.GetValueAsUnsigned() == 1, 'Check that inferior process has completed setup') + + # Find the bundle module, see if we found the dSYM too (they're both in "hide.app") + i = 0 + while i < target.GetNumModules(): + mod = target.GetModuleAtIndex(i) + if mod.GetFileSpec().GetFilename() == 'com.apple.sbd': + dsym_name = mod.GetSymbolFileSpec().GetFilename() + self.assertTrue (dsym_name == 'com.apple.sbd', "Check that we found the dSYM for the bundle that was loaded") + i=i+1 + os.chdir(self.getSourceDir()); + +if __name__ == '__main__': + unittest.main() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/bundle.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/bundle.c new file mode 100644 index 00000000000..c100f9a2c07 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/bundle.c @@ -0,0 +1,4 @@ +int foo () +{ + return 5; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/main.c new file mode 100644 index 00000000000..30761eb1b40 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/main.c @@ -0,0 +1,28 @@ +#include <dlfcn.h> +#include <unistd.h> +#include <stdlib.h> + +int setup_is_complete = 0; + +int main() +{ + + void *handle = dlopen ("com.apple.sbd.xpc/com.apple.sbd", RTLD_NOW); + if (handle) + { + if (dlsym(handle, "foo")) + { + system ("/bin/rm -rf com.apple.sbd.xpc com.apple.sbd.xpc.dSYM"); + setup_is_complete = 1; + + // At this point we want lldb to attach to the process. If lldb attaches + // before we've removed the dlopen'ed bundle, lldb will find the bundle + // at its actual filepath and not have to do any tricky work, invalidating + // the test. + + for (int loop_limiter = 0; loop_limiter < 100; loop_limiter++) + sleep (1); + } + } + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/Info.plist b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/Info.plist new file mode 100644 index 00000000000..82e17116e35 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/Info.plist @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>BuildMachineOSBuild</key> + <string>16B2657</string> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>MyFramework</string> + <key>CFBundleIdentifier</key> + <string>com.apple.test.framework</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>MyFramework</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleShortVersionString</key> + <string>113</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleSupportedPlatforms</key> + <array> + <string>MacOSX</string> + </array> + <key>CFBundleVersion</key> + <string>113</string> + <key>DTCompiler</key> + <string>com.apple.compilers.llvm.clang.1_0</string> + <key>DTPlatformBuild</key> + <string>9L120i</string> + <key>DTPlatformVersion</key> + <string>GM</string> + <key>DTSDKBuild</key> + <string>17A261x</string> + <key>DTSDKName</key> + <string>macosx10.13</string> + <key>DTXcode</key> + <string>0900</string> + <key>DTXcodeBuild</key> + <string>9L120i</string> +</dict> +</plist> diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/Makefile new file mode 100644 index 00000000000..b2a66c2ad41 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/Makefile @@ -0,0 +1,29 @@ +SRCDIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))/ +CC ?= clang + +ifeq "$(ARCH)" "" + ARCH = x86_64 +endif + +CFLAGS ?= -g -O0 -arch $(ARCH) + +all: clean + $(CC) $(CFLAGS) -install_name $(shell pwd)/MyFramework.framework/Versions/A/MyFramework -dynamiclib -o MyFramework $(SRCDIR)/myframework.c + mkdir -p MyFramework.framework/Versions/A/Headers + mkdir -p MyFramework.framework/Versions/A/Resources + cp MyFramework MyFramework.framework/Versions/A + cp $(SRCDIR)/MyFramework.h MyFramework.framework/Versions/A/Headers + cp $(SRCDIR)/Info.plist MyFramework.framework/Versions/A/Resources + ( cd MyFramework.framework/Versions ; ln -s A Current ) + ( cd MyFramework.framework/ ; ln -s Versions/Current/Headers . ) + ( cd MyFramework.framework/ ; ln -s Versions/Current/MyFramework . ) + ( cd MyFramework.framework/ ; ln -s Versions/Current/Resources . ) + mv MyFramework.dSYM MyFramework.framework.dSYM + mkdir hide.app + rm -f MyFramework + tar cf - MyFramework.framework MyFramework.framework.dSYM | ( cd hide.app;tar xBpf -) + $(CC) $(CFLAGS) -o deep-bundle $(SRCDIR)/main.c -F. -framework MyFramework + + +clean: + rm -rf a.out a.out.dSYM deep-bundle deep-bundle.dSYM MyFramework.framework MyFramework.framework.dSYM MyFramework MyFramework.dSYM hide.app diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/MyFramework.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/MyFramework.h new file mode 100644 index 00000000000..a4536647cfc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/MyFramework.h @@ -0,0 +1 @@ +int foo (); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/TestDeepBundle.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/TestDeepBundle.py new file mode 100644 index 00000000000..ecab53587a7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/TestDeepBundle.py @@ -0,0 +1,72 @@ +"""Test that a dSYM can be found when a binary is in a deep bundle with multiple pathname components.""" + + +#import unittest2 +from time import sleep + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +exe_name = 'deep-bundle' # must match Makefile + +class DeepBundleTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfRemote + @skipUnlessDarwin + # This test is explicitly a dSYM test, it doesn't need to run for any other config, but + # the following doesn't work, fixme. + # @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM") + + def setUp(self): + TestBase.setUp(self) + self.source = 'main.c' + + def tearDown(self): + # Destroy process before TestBase.tearDown() + self.dbg.GetSelectedTarget().GetProcess().Destroy() + + # Call super's tearDown(). + TestBase.tearDown(self) + + def test_attach_and_check_dsyms(self): + """Test attach to binary, see if the framework dSYM is found""" + exe = self.getBuildArtifact(exe_name) + self.build() + popen = self.spawnSubprocess(exe, [self.getBuildDir()]) + self.addTearDownHook(self.cleanupSubprocesses) + + # Give the inferior time to start up, dlopen a bundle, remove the bundle it linked in + sleep(5) + + # Since the library that was dlopen()'ed is now removed, lldb will need to find the + # binary & dSYM via target.exec-search-paths + settings_str = "settings set target.exec-search-paths " + self.get_process_working_directory() + "/hide.app" + self.runCmd(settings_str) + self.runCmd("process attach -p " + str(popen.pid)) + + target = self.dbg.GetSelectedTarget() + self.assertTrue(target.IsValid(), 'Should have a valid Target after attaching to process') + + setup_complete = target.FindFirstGlobalVariable("setup_is_complete") + self.assertTrue(setup_complete.GetValueAsUnsigned() == 1, 'Check that inferior process has completed setup') + + # Find the bundle module, see if we found the dSYM too (they're both in "hide.app") + i = 0 + found_module = False + while i < target.GetNumModules(): + mod = target.GetModuleAtIndex(i) + if mod.GetFileSpec().GetFilename() == 'MyFramework': + found_module = True + dsym_name = mod.GetSymbolFileSpec().GetFilename() + self.assertTrue (dsym_name == 'MyFramework', "Check that we found the dSYM for the bundle that was loaded") + i=i+1 + + self.assertTrue(found_module, "Check that we found the framework loaded in lldb's image list") + +if __name__ == '__main__': + unittest.main() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/main.c new file mode 100644 index 00000000000..b5ef5cff74a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/main.c @@ -0,0 +1,27 @@ +#include <MyFramework/MyFramework.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +int setup_is_complete = 0; + +int main(int argc, const char **argv) +{ + char command[8192]; + sprintf (command, + "/bin/rm -rf %s/MyFramework %s/MyFramework.framework %s/MyFramework.framework.dSYM", + argv[1], argv[1], argv[1]); + system (command); + + setup_is_complete = 1; + + // At this point we want lldb to attach to the process. If lldb attaches + // before we've removed the framework we're running against, it will be + // easy for lldb to find the binary & dSYM without using target.exec-search-paths, + // which is the point of this test. + + for (int loop_limiter = 0; loop_limiter < 100; loop_limiter++) + sleep (1); + + return foo(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/myframework.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/myframework.c new file mode 100644 index 00000000000..c100f9a2c07 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/myframework.c @@ -0,0 +1,4 @@ +int foo () +{ + return 5; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/Makefile new file mode 100644 index 00000000000..0d6f5172939 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/Makefile @@ -0,0 +1,8 @@ +CXX_SOURCES := main.cpp +EXE := StripMe +MAKE_DSYM := NO + +include Makefile.rules + +main.o: main.cpp + $(CC) $(CFLAGS_NO_DEBUG) -c $< -o $@ diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/TestFunctionStarts.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/TestFunctionStarts.py new file mode 100644 index 00000000000..e876cdf8b5d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/TestFunctionStarts.py @@ -0,0 +1,86 @@ +""" +Test that we read the function starts section. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +exe_name = "StripMe" # Must match Makefile + +class FunctionStartsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + @skipIfRemote + @skipUnlessDarwin + def test_function_starts_binary(self): + """Test that we make synthetic symbols when we have the binary.""" + self.build() + self.do_function_starts(False) + + @skipIfRemote + @skipUnlessDarwin + def test_function_starts_no_binary(self): + """Test that we make synthetic symbols when we don't have the binary""" + self.build() + self.do_function_starts(True) + + def do_function_starts(self, in_memory): + """Run the binary, stop at our unstripped function, + make sure the caller has synthetic symbols""" + + exe = self.getBuildArtifact(exe_name) + # Now strip the binary, but leave externals so we can break on dont_strip_me. + try: + fail_str = system([["strip", "-u", "-x", "-S", exe]]) + except CalledProcessError as cmd_error: + self.fail("Strip failed: %d"%(cmd_error.returncode)) + + # Use a file as a synchronization point between test and inferior. + pid_file_path = lldbutil.append_to_process_working_directory(self, + "token_pid_%d" % (int(os.getpid()))) + self.addTearDownHook( + lambda: self.run_platform_command( + "rm %s" % + (pid_file_path))) + + popen = self.spawnSubprocess(exe, [pid_file_path]) + self.addTearDownHook(self.cleanupSubprocesses) + + # Wait until process has fully started up. + pid = lldbutil.wait_for_file_on_target(self, pid_file_path) + + if in_memory: + remove_file(exe) + + target = self.dbg.CreateTarget(None) + self.assertTrue(target.IsValid(), "Got a vaid empty target.") + error = lldb.SBError() + attach_info = lldb.SBAttachInfo() + attach_info.SetProcessID(popen.pid) + attach_info.SetIgnoreExisting(False) + process = target.Attach(attach_info, error) + self.assertTrue(error.Success(), "Didn't attach successfully to %d: %s"%(popen.pid, error.GetCString())) + + bkpt = target.BreakpointCreateByName("dont_strip_me", exe) + self.assertTrue(bkpt.GetNumLocations() > 0, "Didn't set the dont_strip_me bkpt.") + + threads = lldbutil.continue_to_breakpoint(process, bkpt) + self.assertEqual(len(threads), 1, "Didn't hit my breakpoint.") + + # Our caller frame should have been stripped. Make sure we made a synthetic symbol + # for it: + thread = threads[0] + self.assertTrue(thread.num_frames > 1, "Couldn't backtrace.") + name = thread.frame[1].GetFunctionName() + self.assertTrue(name.startswith("___lldb_unnamed_symbol")) + self.assertTrue(name.endswith("$$StripMe")) + + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/main.cpp new file mode 100644 index 00000000000..188078a22ed --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/function-starts/main.cpp @@ -0,0 +1,32 @@ +#include <stdio.h> +#include <fcntl.h> + +#include <chrono> +#include <fstream> +#include <thread> + +extern void dont_strip_me() +{ + printf("I wasn't stripped\n"); +} + +static void *a_function() +{ + while (1) + { + std::this_thread::sleep_for(std::chrono::microseconds(100)); + dont_strip_me(); + } + return 0; +} + +int main(int argc, char const *argv[]) +{ + { + // Create file to signal that this process has started up. + std::ofstream f; + f.open(argv[1]); + } + a_function(); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/Makefile new file mode 100644 index 00000000000..929ed58f757 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/Makefile @@ -0,0 +1,16 @@ +C_SOURCES := main.c +LD_EXTRAS := -L. -lindirect -lreexport + +.PHONY: build-libindirect build-libreepxoprt +all: build-libindirect build-libreepxoprt a.out + +include Makefile.rules + +build-libindirect: indirect.c + $(MAKE) -f $(MAKEFILE_RULES) \ + DYLIB_C_SOURCES=indirect.c DYLIB_NAME=indirect DYLIB_ONLY=YES + +build-libreepxoprt: reexport.c + $(MAKE) -f $(MAKEFILE_RULES) \ + DYLIB_C_SOURCES=reexport.c DYLIB_NAME=reexport DYLIB_ONLY=YES \ + LD_EXTRAS="-L. -lindirect -Wl,-alias_list,$(SRCDIR)/alias.list" diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/TestIndirectSymbols.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/TestIndirectSymbols.py new file mode 100644 index 00000000000..2718bd746a0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/TestIndirectSymbols.py @@ -0,0 +1,115 @@ +"""Test stepping and setting breakpoints in indirect and re-exported symbols.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestIndirectFunctions(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + + @skipUnlessDarwin + @expectedFailureAll(oslist=no_match(["macosx"]), bugnumber="rdar://55952764") + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test stepping and setting breakpoints in indirect and re-exported symbols.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + if self.platformIsDarwin(): + lib1 = self.getBuildArtifact('libindirect.dylib') + lib2 = self.getBuildArtifact('libreexport.dylib') + self.registerSharedLibrariesWithTarget(target, [lib1, lib2]) + + self.main_source_spec = lldb.SBFileSpec(self.main_source) + + break1 = target.BreakpointCreateBySourceRegex( + "Set breakpoint here to step in indirect.", self.main_source_spec) + self.assertTrue(break1, VALID_BREAKPOINT) + + break2 = target.BreakpointCreateBySourceRegex( + "Set breakpoint here to step in reexported.", self.main_source_spec) + self.assertTrue(break2, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint 1.") + + thread = threads[0] + + # Now do a step-into, and we should end up in the hidden target of this + # indirect function. + thread.StepInto() + curr_function = thread.GetFrameAtIndex(0).GetFunctionName() + self.assertEqual(curr_function, "call_through_indirect_hidden", + "Stepped into indirect symbols.") + + # Now set a breakpoint using the indirect symbol name, and make sure we + # get to that: + break_indirect = target.BreakpointCreateByName("call_through_indirect") + self.assertTrue(break_indirect, VALID_BREAKPOINT) + + # Now continue should take us to the second call through the indirect + # symbol: + + threads = lldbutil.continue_to_breakpoint(process, break_indirect) + self.assertTrue( + len(threads) == 1, + "Stopped at breakpoint in indirect function.") + curr_function = thread.GetFrameAtIndex(0).GetFunctionName() + self.assertTrue( + curr_function == "call_through_indirect_hidden", + "Stepped into indirect symbols.") + + # Delete this breakpoint so it won't get in the way: + target.BreakpointDelete(break_indirect.GetID()) + + # Now continue to the site of the first re-exported function call in + # main: + threads = lldbutil.continue_to_breakpoint(process, break2) + + # This is stepping Into through a re-exported symbol to an indirect + # symbol: + thread.StepInto() + curr_function = thread.GetFrameAtIndex(0).GetFunctionName() + self.assertTrue( + curr_function == "call_through_indirect_hidden", + "Stepped into indirect symbols.") + + # And the last bit is to set a breakpoint on the re-exported symbol and + # make sure we are again in out target function. + break_reexported = target.BreakpointCreateByName( + "reexport_to_indirect") + self.assertTrue(break_reexported, VALID_BREAKPOINT) + + # Now continue should take us to the second call through the indirect + # symbol: + + threads = lldbutil.continue_to_breakpoint(process, break_reexported) + self.assertTrue( + len(threads) == 1, + "Stopped at breakpoint in reexported function target.") + curr_function = thread.GetFrameAtIndex(0).GetFunctionName() + self.assertTrue( + curr_function == "call_through_indirect_hidden", + "Stepped into indirect symbols.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/alias.list b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/alias.list new file mode 100644 index 00000000000..3232c588837 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/alias.list @@ -0,0 +1 @@ +_call_through_indirect _reexport_to_indirect
\ No newline at end of file diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/indirect.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/indirect.c new file mode 100644 index 00000000000..48e1459bb59 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/indirect.c @@ -0,0 +1,14 @@ +#define MakeResolver(name) \ + void * name ## Resolver(void) __asm__("_" #name); \ + void * name ## Resolver(void) { \ + __asm__(".symbol_resolver _" #name); \ + return name ## _hidden; \ + } + +int +call_through_indirect_hidden(int arg) +{ + return arg + 5; +} + +MakeResolver(call_through_indirect) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/main.c new file mode 100644 index 00000000000..b5af058d00b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/main.c @@ -0,0 +1,14 @@ +extern int call_through_indirect(int); +extern int reexport_to_indirect(int); + +int +main () +{ + int indirect_result = call_through_indirect(20); // Set breakpoint here to step in indirect. + indirect_result = call_through_indirect(30); + + int reexport_result = reexport_to_indirect (20); // Set breakpoint here to step in reexported. + reexport_result = reexport_to_indirect (30); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/reexport.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/reexport.c new file mode 100644 index 00000000000..096a463b3a4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/indirect_symbol/reexport.c @@ -0,0 +1,7 @@ +extern int call_through_indirect(int); + +int +fake_call_through_reexport(int value) +{ + return value + 10; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/Makefile new file mode 100644 index 00000000000..ad37346bbeb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/Makefile @@ -0,0 +1,11 @@ +MAKE_DSYM := NO + +C_SOURCES := main.c + +all: a.out create-empty-corefile + +create-empty-corefile: + $(MAKE) -f $(MAKEFILE_RULES) EXE=create-empty-corefile \ + C_SOURCES=create-empty-corefile.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/TestKernVerStrLCNOTE.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/TestKernVerStrLCNOTE.py new file mode 100644 index 00000000000..80007438add --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/TestKernVerStrLCNOTE.py @@ -0,0 +1,99 @@ +"""Test that corefiles with an LC_NOTE "kern ver str" load command is used.""" + + + +import os +import re +import subprocess + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestKernVerStrLCNOTE(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM") + @skipIfDarwinEmbedded + @skipUnlessDarwin + def test_lc_note(self): + self.build() + self.test_exe = self.getBuildArtifact("a.out") + self.create_corefile = self.getBuildArtifact("create-empty-corefile") + self.dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh") + self.corefile = self.getBuildArtifact("core") + + ## We can hook in our dsym-for-uuid shell script to lldb with this env + ## var instead of requiring a defaults write. + os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = self.dsym_for_uuid + self.addTearDownHook(lambda: os.environ.pop('LLDB_APPLE_DSYMFORUUID_EXECUTABLE', None)) + + dwarfdump_uuid_regex = re.compile( + 'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*') + dwarfdump_cmd_output = subprocess.check_output( + ('/usr/bin/dwarfdump --uuid "%s"' % self.test_exe), shell=True).decode("utf-8") + aout_uuid = None + for line in dwarfdump_cmd_output.splitlines(): + match = dwarfdump_uuid_regex.search(line) + if match: + aout_uuid = match.group(1) + self.assertNotEqual(aout_uuid, None, "Could not get uuid of built a.out") + + ### Create our dsym-for-uuid shell script which returns self.test_exe + ### and its dSYM when given self.test_exe's UUID. + shell_cmds = [ + '#! /bin/sh', + 'ret=0', + 'echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>"', + 'echo "<!DOCTYPE plist PUBLIC \\"-//Apple//DTD PLIST 1.0//EN\\" \\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\">"', + 'echo "<plist version=\\"1.0\\">"', + '', + '# the last arugment is probably the uuid', + 'while [ $# -gt 1 ]', + 'do', + ' shift', + 'done', + 'echo "<dict><key>$1</key><dict>"', + '', + 'if [ "$1" = "%s" ]' % aout_uuid, + 'then', + ' echo "<key>DBGArchitecture</key><string>x86_64</string>"', + ' echo "<key>DBGDSYMPath</key><string>%s.dSYM/Contents/Resources/DWARF/%s</string>"' % (self.test_exe, os.path.basename(self.test_exe)), + ' echo "<key>DBGSymbolRichExecutable</key><string>%s</string>"' % self.test_exe, + 'else', + ' echo "<key>DBGError</key><string>not found</string>"', + ' ret=1', + 'fi', + 'echo "</dict></dict></plist>"', + 'exit $ret' + ] + + with open(self.dsym_for_uuid, "w") as writer: + for l in shell_cmds: + writer.write(l + '\n') + + os.chmod(self.dsym_for_uuid, 0o755) + + ### Create our corefile + retcode = call(self.create_corefile + " " + self.corefile + " " + self.test_exe, shell=True) + + ### Now run lldb on the corefile + ### which will give us a UUID + ### which we call dsym-for-uuid.sh with + ### which gives us a binary and dSYM + ### which lldb should load! + + + self.target = self.dbg.CreateTarget('') + err = lldb.SBError() + self.process = self.target.LoadCore(self.corefile) + self.assertEqual(self.process.IsValid(), True) + if self.TraceOn(): + self.runCmd("image list") + self.assertEqual(self.target.GetNumModules(), 1) + fspec = self.target.GetModuleAtIndex(0).GetFileSpec() + filepath = fspec.GetDirectory() + "/" + fspec.GetFilename() + self.assertEqual(filepath, self.test_exe) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.cpp new file mode 100644 index 00000000000..8a8115af967 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.cpp @@ -0,0 +1,315 @@ +#include <stdio.h> +#include <stdlib.h> +#include <mach-o/loader.h> +#include <vector> +#include <string> +#include <mach/thread_status.h> +#include <string.h> +#include <uuid/uuid.h> + +// Create an empty corefile with a "kern ver str" LC_NOTE. +// If an existing binary is given as an optional 2nd argument on the cmd line, +// the UUID from that binary will be encoded in the corefile. +// Otherwise a pre-set UUID will be put in the corefile that +// is created. + + +union uint32_buf { + uint8_t bytebuf[4]; + uint32_t val; +}; + +union uint64_buf { + uint8_t bytebuf[8]; + uint64_t val; +}; + +void +add_uint64(std::vector<uint8_t> &buf, uint64_t val) +{ + uint64_buf conv; + conv.val = val; + for (int i = 0; i < 8; i++) + buf.push_back(conv.bytebuf[i]); +} + +void +add_uint32(std::vector<uint8_t> &buf, uint32_t val) +{ + uint32_buf conv; + conv.val = val; + for (int i = 0; i < 4; i++) + buf.push_back(conv.bytebuf[i]); +} + +std::vector<uint8_t> +x86_lc_thread_load_command () +{ + std::vector<uint8_t> data; + add_uint32 (data, LC_THREAD); // thread_command.cmd + add_uint32 (data, 184); // thread_command.cmdsize + add_uint32 (data, x86_THREAD_STATE64); // thread_command.flavor + add_uint32 (data, x86_THREAD_STATE64_COUNT); // thread_command.count + add_uint64 (data, 0x0000000000000000); // rax + add_uint64 (data, 0x0000000000000400); // rbx + add_uint64 (data, 0x0000000000000000); // rcx + add_uint64 (data, 0x0000000000000000); // rdx + add_uint64 (data, 0x0000000000000000); // rdi + add_uint64 (data, 0x0000000000000000); // rsi + add_uint64 (data, 0xffffff9246e2ba20); // rbp + add_uint64 (data, 0xffffff9246e2ba10); // rsp + add_uint64 (data, 0x0000000000000000); // r8 + add_uint64 (data, 0x0000000000000000); // r9 + add_uint64 (data, 0x0000000000000000); // r10 + add_uint64 (data, 0x0000000000000000); // r11 + add_uint64 (data, 0xffffff7f96ce5fe1); // r12 + add_uint64 (data, 0x0000000000000000); // r13 + add_uint64 (data, 0x0000000000000000); // r14 + add_uint64 (data, 0xffffff9246e2bac0); // r15 + add_uint64 (data, 0xffffff8015a8f6d0); // rip + add_uint64 (data, 0x0000000000011111); // rflags + add_uint64 (data, 0x0000000000022222); // cs + add_uint64 (data, 0x0000000000033333); // fs + add_uint64 (data, 0x0000000000044444); // gs + return data; +} + +void +add_lc_note_kern_ver_str_load_command (std::vector<std::vector<uint8_t> > &loadcmds, + std::vector<uint8_t> &payload, + int payload_file_offset, + std::string ident) +{ + std::vector<uint8_t> loadcmd_data; + + add_uint32 (loadcmd_data, LC_NOTE); // note_command.cmd + add_uint32 (loadcmd_data, 40); // note_command.cmdsize + char lc_note_name[16]; + memset (lc_note_name, 0, 16); + strcpy (lc_note_name, "kern ver str"); + + // lc_note.data_owner + for (int i = 0; i < 16; i++) + loadcmd_data.push_back (lc_note_name[i]); + + // we start writing the payload at payload_file_offset to leave + // room at the start for the header & the load commands. + uint64_t current_payload_offset = payload.size() + payload_file_offset; + + add_uint64 (loadcmd_data, current_payload_offset); // note_command.offset + add_uint64 (loadcmd_data, 4 + ident.size() + 1); // note_command.size + + loadcmds.push_back (loadcmd_data); + + add_uint32 (payload, 1); // kerneL_version_string.version + for (int i = 0; i < ident.size() + 1; i++) + { + payload.push_back (ident[i]); + } +} + +void +add_lc_segment (std::vector<std::vector<uint8_t> > &loadcmds, + std::vector<uint8_t> &payload, + int payload_file_offset) +{ + std::vector<uint8_t> loadcmd_data; + struct segment_command_64 seg; + seg.cmd = LC_SEGMENT_64; + seg.cmdsize = sizeof (struct segment_command_64); // no sections + memset (seg.segname, 0, 16); + seg.vmaddr = 0xffffff7f96400000; + seg.vmsize = 4096; + seg.fileoff = payload.size() + payload_file_offset; + seg.filesize = 0; + seg.maxprot = 1; + seg.initprot = 1; + seg.nsects = 0; + seg.flags = 0; + + uint8_t *p = (uint8_t*) &seg; + for (int i = 0; i < sizeof (struct segment_command_64); i++) + { + loadcmd_data.push_back (*(p + i)); + } + loadcmds.push_back (loadcmd_data); +} + +std::string +get_uuid_from_binary (const char *fn) +{ + FILE *f = fopen(fn, "r"); + if (f == nullptr) + { + fprintf (stderr, "Unable to open binary '%s' to get uuid\n", fn); + exit(1); + } + uint32_t num_of_load_cmds = 0; + uint32_t size_of_load_cmds = 0; + std::string uuid; + off_t file_offset = 0; + + uint8_t magic[4]; + if (::fread (magic, 1, 4, f) != 4) + { + fprintf (stderr, "Failed to read magic number from input file %s\n", fn); + exit (1); + } + uint8_t magic_32_be[] = {0xfe, 0xed, 0xfa, 0xce}; + uint8_t magic_32_le[] = {0xce, 0xfa, 0xed, 0xfe}; + uint8_t magic_64_be[] = {0xfe, 0xed, 0xfa, 0xcf}; + uint8_t magic_64_le[] = {0xcf, 0xfa, 0xed, 0xfe}; + + if (memcmp (magic, magic_32_be, 4) == 0 || memcmp (magic, magic_64_be, 4) == 0) + { + fprintf (stderr, "big endian corefiles not supported\n"); + exit (1); + } + + ::fseeko (f, 0, SEEK_SET); + if (memcmp (magic, magic_32_le, 4) == 0) + { + struct mach_header mh; + if (::fread (&mh, 1, sizeof (mh), f) != sizeof (mh)) + { + fprintf (stderr, "error reading mach header from input file\n"); + exit (1); + } + if (mh.cputype != CPU_TYPE_X86_64) + { + fprintf (stderr, "This tool creates an x86_64 corefile but " + "the supplied binary '%s' is cputype 0x%x\n", + fn, (uint32_t) mh.cputype); + exit (1); + } + num_of_load_cmds = mh.ncmds; + size_of_load_cmds = mh.sizeofcmds; + file_offset += sizeof (struct mach_header); + } + else + { + struct mach_header_64 mh; + if (::fread (&mh, 1, sizeof (mh), f) != sizeof (mh)) + { + fprintf (stderr, "error reading mach header from input file\n"); + exit (1); + } + if (mh.cputype != CPU_TYPE_X86_64) + { + fprintf (stderr, "This tool creates an x86_64 corefile but " + "the supplied binary '%s' is cputype 0x%x\n", + fn, (uint32_t) mh.cputype); + exit (1); + } + num_of_load_cmds = mh.ncmds; + size_of_load_cmds = mh.sizeofcmds; + file_offset += sizeof (struct mach_header_64); + } + + off_t load_cmds_offset = file_offset; + + for (int i = 0; i < num_of_load_cmds && (file_offset - load_cmds_offset) < size_of_load_cmds; i++) + { + ::fseeko (f, file_offset, SEEK_SET); + uint32_t cmd; + uint32_t cmdsize; + ::fread (&cmd, sizeof (uint32_t), 1, f); + ::fread (&cmdsize, sizeof (uint32_t), 1, f); + if (cmd == LC_UUID) + { + struct uuid_command uuidcmd; + ::fseeko (f, file_offset, SEEK_SET); + if (::fread (&uuidcmd, 1, sizeof (uuidcmd), f) != sizeof (uuidcmd)) + { + fprintf (stderr, "Unable to read LC_UUID load command.\n"); + exit (1); + } + uuid_string_t uuidstr; + uuid_unparse (uuidcmd.uuid, uuidstr); + uuid = uuidstr; + break; + } + file_offset += cmdsize; + } + return uuid; +} + +int main (int argc, char **argv) +{ + if (argc != 2 && argc != 3) + { + fprintf (stderr, "usage: create-empty-corefile <output-core-name> [binary-to-copy-uuid-from]\n"); + fprintf (stderr, "Create a Mach-O corefile with an LC_NOTE 'kern ver str' load command/payload\n"); + fprintf (stderr, "If a binary is given as a second argument, the Mach-O UUID of that file will\n"); + fprintf (stderr, "be read and used in the corefile's LC_NOTE payload.\n"); + exit (1); + } + + std::string ident = "EFI UUID=3F9BA21F-55EA-356A-A349-BBA6F51FE8B1"; + if (argc == 3) + { + std::string uuid_from_file = get_uuid_from_binary (argv[2]); + if (!uuid_from_file.empty()) + { + ident = "EFI UUID="; + ident += uuid_from_file; + } + } + + // An array of load commands (in the form of byte arrays) + std::vector<std::vector<uint8_t> > load_commands; + + // An array of corefile contents (page data, lc_note data, etc) + std::vector<uint8_t> payload; + + // First add all the load commands / payload so we can figure out how large + // the load commands will actually be. + load_commands.push_back (x86_lc_thread_load_command()); + add_lc_note_kern_ver_str_load_command (load_commands, payload, 0, ident); + add_lc_segment (load_commands, payload, 0); + + int size_of_load_commands = 0; + for (const auto &lc : load_commands) + size_of_load_commands += lc.size(); + + int header_and_load_cmd_room = sizeof (struct mach_header_64) + size_of_load_commands; + + // Erease the load commands / payload now that we know how much space is needed, + // redo it. + load_commands.clear(); + payload.clear(); + + load_commands.push_back (x86_lc_thread_load_command()); + add_lc_note_kern_ver_str_load_command (load_commands, payload, header_and_load_cmd_room, ident); + add_lc_segment (load_commands, payload, header_and_load_cmd_room); + + struct mach_header_64 mh; + mh.magic = MH_MAGIC_64; + mh.cputype = CPU_TYPE_X86_64; + mh.cpusubtype = CPU_SUBTYPE_X86_64_ALL; + mh.filetype = MH_CORE; + mh.ncmds = load_commands.size(); + mh.sizeofcmds = size_of_load_commands; + mh.flags = 0; + mh.reserved = 0; + + + FILE *f = fopen (argv[1], "w"); + + if (f == nullptr) + { + fprintf (stderr, "Unable to open file %s for writing\n", argv[1]); + exit (1); + } + + fwrite (&mh, sizeof (struct mach_header_64), 1, f); + + for (const auto &lc : load_commands) + fwrite (lc.data(), lc.size(), 1, f); + + fseek (f, header_and_load_cmd_room, SEEK_SET); + + fwrite (payload.data(), payload.size(), 1, f); + + fclose (f); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/main.c new file mode 100644 index 00000000000..70a72e0b80b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/main.c @@ -0,0 +1,2 @@ +#include <stdio.h> +int main () { puts ("this is the lc-note test program."); } diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/load-kext/TestLoadKext.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/load-kext/TestLoadKext.py new file mode 100644 index 00000000000..ec35ce854d8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/load-kext/TestLoadKext.py @@ -0,0 +1,35 @@ +""" +Test loading of a kext binary. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LoadKextTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + #super(LoadKextTestCase, self).setUp() + #self._initial_platform = lldb.DBG.GetSelectedPlatform() + + def test_load_kext(self): + """Test that lldb can load a kext binary.""" + + # Create kext from YAML. + self.yaml2obj("mykext.yaml", self.getBuildArtifact("mykext")) + + target = self.dbg.CreateTarget(self.getBuildArtifact("mykext")) + + self.assertTrue(target.IsValid()) + + self.assertEqual(target.GetNumModules(), 1) + mod = target.GetModuleAtIndex(0) + self.assertEqual(mod.GetFileSpec().GetFilename(), "mykext") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/load-kext/mykext.yaml b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/load-kext/mykext.yaml new file mode 100644 index 00000000000..ccf016304c8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/load-kext/mykext.yaml @@ -0,0 +1,222 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x0000000B + ncmds: 7 + sizeofcmds: 520 + flags: 0x00000085 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __TEXT + vmaddr: 0 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 7 + initprot: 5 + nsects: 1 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000000000F60 + size: 158 + offset: 0x00000F60 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 152 + segname: __DATA + vmaddr: 4096 + vmsize: 4096 + fileoff: 4096 + filesize: 4096 + maxprot: 7 + initprot: 3 + nsects: 1 + flags: 0 + Sections: + - sectname: __data + segname: __DATA + addr: 0x0000000000001000 + size: 220 + offset: 0x00001000 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 8192 + vmsize: 4096 + fileoff: 8192 + filesize: 800 + maxprot: 7 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 8224 + nsyms: 19 + stroff: 8528 + strsize: 464 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 16 + iextdefsym: 16 + nextdefsym: 3 + iundefsym: 19 + nundefsym: 0 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 8192 + nlocrel: 4 + - cmd: LC_UUID + cmdsize: 24 + uuid: 17A97B33-09B7-3195-9408-DBD965D578A5 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 +LinkEditData: + NameList: + - n_strx: 40 + n_type: 0x64 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 141 + n_type: 0x64 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 155 + n_type: 0x66 + n_sect: 3 + n_desc: 1 + n_value: 1543540349 + - n_strx: 276 + n_type: 0x20 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 287 + n_type: 0x20 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 298 + n_type: 0x20 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 309 + n_type: 0x20 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 1 + n_type: 0x64 + n_sect: 1 + n_desc: 0 + n_value: 0 + - n_strx: 325 + n_type: 0x1E + n_sect: 1 + n_desc: 0 + n_value: 3992 + - n_strx: 333 + n_type: 0x1E + n_sect: 1 + n_desc: 0 + n_value: 4018 + - n_strx: 361 + n_type: 0x1E + n_sect: 1 + n_desc: 0 + n_value: 4035 + - n_strx: 392 + n_type: 0x1E + n_sect: 1 + n_desc: 0 + n_value: 4052 + - n_strx: 417 + n_type: 0x1E + n_sect: 1 + n_desc: 0 + n_value: 4068 + - n_strx: 424 + n_type: 0x1E + n_sect: 2 + n_desc: 0 + n_value: 4296 + - n_strx: 435 + n_type: 0x1E + n_sect: 2 + n_desc: 0 + n_value: 4304 + - n_strx: 446 + n_type: 0x1E + n_sect: 2 + n_desc: 0 + n_value: 4312 + - n_strx: 2 + n_type: 0x0F + n_sect: 2 + n_desc: 0 + n_value: 4096 + - n_strx: 13 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 3936 + - n_strx: 27 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 3968 + StringTable: + - ' ' + - _kmod_info + - _mykext_start + - _mykext_stop + - /tmp/mykext/build/mykext/Build/Intermediates.noindex/mykext.build/Debug/mykext.build/DerivedSources/ + - mykext_info.c + - /tmp/mykext/build/mykext/Build/Intermediates.noindex/mykext.build/Debug/mykext.build/Objects-normal/x86_64/mykext_info.o + - _kmod_info + - __realmain + - __antimain + - __kext_apple_cc + - __start + - _OSKextGetCurrentIdentifier + - _OSKextGetCurrentVersionString + - _OSKextGetCurrentLoadTag + - __stop + - __realmain + - __antimain + - __kext_apple_cc + - '' + - '' +... diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/Makefile new file mode 100644 index 00000000000..2123af1dd70 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/Makefile @@ -0,0 +1,13 @@ +C_SOURCES := main.c +LD_EXTRAS := -L. -lfoo + +TRIPLE := x86_64-apple-ios13.0-macabi +CFLAGS_EXTRAS := -target $(TRIPLE) + +all: libfoo.dylib a.out + +libfoo.dylib: foo.c + $(MAKE) -f $(MAKEFILE_RULES) \ + DYLIB_ONLY=YES DYLIB_NAME=foo DYLIB_C_SOURCES=foo.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/TestMacABImacOSFramework.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/TestMacABImacOSFramework.py new file mode 100644 index 00000000000..23b26772554 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/TestMacABImacOSFramework.py @@ -0,0 +1,28 @@ +# TestMacABImacOSFramework.py +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil +import os +import unittest2 + + +class TestMacABImacOSFramework(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(macos_version=["<", "10.15"]) + @skipUnlessDarwin + @skipIfDarwinEmbedded + # There is a Clang driver change missing on llvm.org. + @expectedFailureAll(bugnumber="rdar://problem/54986190>") + def test_macabi(self): + """Test the x86_64-apple-ios-macabi target linked against a macos dylib""" + self.build() + lldbutil.run_to_source_breakpoint(self, "break here", + lldb.SBFileSpec('main.c')) + self.expect("image list -t -b", + patterns=["x86_64.*-apple-ios.*-macabi a\.out", + "x86_64.*-apple-macosx.* libfoo.dylib[^(]"]) + self.expect("fr v s", "Hello MacABI") + self.expect("p s", "Hello MacABI") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.c new file mode 100644 index 00000000000..9c29d590f26 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.c @@ -0,0 +1,8 @@ +#include "foo.h" + +void stop() {} + +int foo() { + stop(); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.h new file mode 100644 index 00000000000..5d5f8f0c9e7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/foo.h @@ -0,0 +1 @@ +int foo(); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/main.c new file mode 100644 index 00000000000..92069d902fd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/macabi/main.c @@ -0,0 +1,5 @@ +#include "foo.h" +int main() { + const char *s = "Hello MacABI!"; + return foo(); // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/Makefile new file mode 100644 index 00000000000..a68dad547ec --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS = -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/TestDarwinNSLogOutput.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/TestDarwinNSLogOutput.py new file mode 100644 index 00000000000..2ab217d600b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/TestDarwinNSLogOutput.py @@ -0,0 +1,155 @@ +""" +Test DarwinLog "source include debug-level" functionality provided by the +StructuredDataDarwinLog plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + + +import lldb +import platform +import re + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbtest_config + + +class DarwinNSLogOutputTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @skipIfRemote # this test is currently written using lldb commands & assumes running on local system + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + self.child = None + self.child_prompt = '(lldb) ' + self.strict_sources = False + + # Source filename. + self.source = 'main.m' + + # Output filename. + self.exe_name = self.getBuildArtifact("a.out") + self.d = {'OBJC_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(DarwinNSLogOutputTestCase, self).tearDown() + + def run_lldb_to_breakpoint(self, exe, source_file, line, + settings_commands=None): + # Set self.child_prompt, which is "(lldb) ". + prompt = self.child_prompt + + # So that the child gets torn down after the test. + import pexpect + import sys + if sys.version_info.major == 3: + self.child = pexpect.spawnu('%s %s %s' % (lldbtest_config.lldbExec, + self.lldbOption, exe)) + else: + 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 + + # Disable showing of source lines at our breakpoint. + # This is necessary for the logging tests, because the very + # text we want to match for output from the running inferior + # will show up in the source as well. We don't want the source + # output to erroneously make a match with our expected output. + self.runCmd("settings set stop-line-count-before 0") + self.expect_prompt() + self.runCmd("settings set stop-line-count-after 0") + self.expect_prompt() + + # Run any test-specific settings commands now. + if settings_commands is not None: + for setting_command in settings_commands: + self.runCmd(setting_command) + self.expect_prompt() + + # Set the breakpoint, and run to it. + child.sendline('breakpoint set -f %s -l %d' % (source_file, line)) + child.expect_exact(prompt) + child.sendline('run') + child.expect_exact(prompt) + + # Ensure we stopped at a breakpoint. + self.runCmd("thread list") + self.expect(re.compile(r"stop reason = .*breakpoint")) + + def runCmd(self, cmd): + if self.child: + self.child.sendline(cmd) + + def expect_prompt(self, exactly=True): + self.expect(self.child_prompt, exactly=exactly) + + def expect(self, pattern, exactly=False, *args, **kwargs): + if exactly: + return self.child.expect_exact(pattern, *args, **kwargs) + return self.child.expect(pattern, *args, **kwargs) + + def do_test(self, expect_regexes=None, settings_commands=None): + """ Run a test. """ + self.build(dictionary=self.d) + self.setTearDownCleanup(dictionary=self.d) + + exe = self.getBuildArtifact(self.exe_name) + self.run_lldb_to_breakpoint(exe, self.source, self.line, + settings_commands=settings_commands) + self.expect_prompt() + + # Now go. + self.runCmd("process continue") + self.expect(expect_regexes) + + def test_nslog_output_is_displayed(self): + """Test that NSLog() output shows up in the command-line debugger.""" + self.do_test(expect_regexes=[ + re.compile(r"(This is a message from NSLog)"), + re.compile(r"Process \d+ exited with status") + ]) + self.assertIsNotNone(self.child.match) + self.assertGreater(len(self.child.match.groups()), 0) + self.assertEqual( + "This is a message from NSLog", + self.child.match.group(1)) + + def test_nslog_output_is_suppressed_with_env_var(self): + """Test that NSLog() output does not show up with the ignore env var.""" + # This test will only work properly on macOS 10.12+. Skip it on earlier versions. + # This will require some tweaking on iOS. + match = re.match(r"^\d+\.(\d+)", platform.mac_ver()[0]) + if match is None or int(match.group(1)) < 12: + self.skipTest("requires macOS 10.12 or higher") + + self.do_test( + expect_regexes=[ + re.compile(r"(This is a message from NSLog)"), + re.compile(r"Process \d+ exited with status") + ], + settings_commands=[ + "settings set target.env-vars " + "\"IDE_DISABLED_OS_ACTIVITY_DT_MODE=1\"" + ]) + self.assertIsNotNone(self.child.match) + self.assertEqual(len(self.child.match.groups()), 0) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/main.m new file mode 100644 index 00000000000..d48536496b8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/nslog/main.m @@ -0,0 +1,17 @@ +//===-- main.m --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <Foundation/Foundation.h> + +int main(int argc, char** argv) +{ + printf("About to log\n"); // break here + NSLog(@"This is a message from NSLog"); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/Makefile new file mode 100644 index 00000000000..ee67988d065 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/Makefile @@ -0,0 +1,5 @@ +C_SOURCES := main.c +LD_EXTRAS = -Xlinker -order_file -Xlinker $(SRCDIR)/order-file +MAKE_DSYM := NO + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/TestOrderFile.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/TestOrderFile.py new file mode 100644 index 00000000000..778d06ddaca --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/TestOrderFile.py @@ -0,0 +1,36 @@ +""" +Test that debug symbols have the correct order as specified by the order file. +""" + + + +import re +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class OrderFileTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test(self): + """Test debug symbols follow the correct order by the order file.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Test that the debug symbols have Function f3 before Function f1. + # Use "-s address" option to sort by address. + self.runCmd("image dump symtab -s address %s" % exe) + output = self.res.GetOutput() + mo_f3 = re.search("Code +.+f3", output) + mo_f1 = re.search("Code +.+f1", output) + + # Match objects for f3 and f1 must exist and f3 must come before f1. + self.assertTrue(mo_f3 and mo_f1 and mo_f3.start() < mo_f1.start(), + "Symbols have correct order by the order file") + + self.runCmd("run", RUN_COMPLETED) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/cmds.txt b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/cmds.txt new file mode 100644 index 00000000000..8c51dd763bf --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/cmds.txt @@ -0,0 +1,3 @@ +b main.c:41 +c +lines -shlib a.out main.c diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/main.c new file mode 100644 index 00000000000..18ee77685c9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/main.c @@ -0,0 +1,53 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + + +int f1 (char *s); +int f2 (char *s); +int f3 (char *s); + + +// We want f1 to start on line 20 +int f1 (char *s) +{ + return printf("f1: %s\n", s); +} + + + + + +// We want f2 to start on line 30 +int f2 (char *s) +{ + return printf("f2: %s\n", s); +} + + + + + +// We want f3 to start on line 40 +int f3 (char *s) +{ + return printf("f3: %s\n", s); +} + + + + + +// We want main to start on line 50 +int main (int argc, const char * argv[]) +{ + f1("carp"); + f2("ding"); + f3("dong"); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/order-file b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/order-file new file mode 100644 index 00000000000..0cf8ecd2a63 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/order/order-file @@ -0,0 +1,4 @@ +main.o:_f3 +main.o:_main +main.o:_f2 +main.o:_f1 diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/TestQueues.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/TestQueues.py new file mode 100644 index 00000000000..805ad21a413 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/TestQueues.py @@ -0,0 +1,391 @@ +"""Test queues inspection SB APIs.""" + +from __future__ import print_function + + +import unittest2 +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestQueues(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api_queues(self): + """Test queues inspection SB APIs.""" + self.build() + self.queues() + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api_queues_with_backtrace(self): + """Test queues inspection SB APIs.""" + self.build() + self.queues_with_libBacktraceRecording() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + + def check_queue_for_valid_queue_id(self, queue): + self.assertTrue( + queue.GetQueueID() != 0, "Check queue %s for valid QueueID (got 0x%x)" % + (queue.GetName(), queue.GetQueueID())) + + def check_running_and_pending_items_on_queue( + self, queue, expected_running, expected_pending): + self.assertTrue( + queue.GetNumPendingItems() == expected_pending, + "queue %s should have %d pending items, instead has %d pending items" % + (queue.GetName(), + expected_pending, + (queue.GetNumPendingItems()))) + self.assertTrue( + queue.GetNumRunningItems() == expected_running, + "queue %s should have %d running items, instead has %d running items" % + (queue.GetName(), + expected_running, + (queue.GetNumRunningItems()))) + + def describe_threads(self): + desc = [] + for x in self.inferior_process: + id = x.GetIndexID() + reason_str = lldbutil.stop_reason_to_str(x.GetStopReason()) + + location = "\t".join([lldbutil.get_description( + x.GetFrameAtIndex(i)) for i in range(x.GetNumFrames())]) + desc.append( + "thread %d: %s (queue id: %s) at\n\t%s" % + (id, reason_str, x.GetQueueID(), location)) + print('\n'.join(desc)) + + def check_number_of_threads_owned_by_queue(self, queue, number_threads): + if (queue.GetNumThreads() != number_threads): + self.describe_threads() + + self.assertTrue( + queue.GetNumThreads() == number_threads, + "queue %s should have %d thread executing, but has %d" % + (queue.GetName(), + number_threads, + queue.GetNumThreads())) + + def check_queue_kind(self, queue, kind): + expected_kind_string = "Unknown" + if kind == lldb.eQueueKindSerial: + expected_kind_string = "Serial queue" + if kind == lldb.eQueueKindConcurrent: + expected_kind_string = "Concurrent queue" + actual_kind_string = "Unknown" + if queue.GetKind() == lldb.eQueueKindSerial: + actual_kind_string = "Serial queue" + if queue.GetKind() == lldb.eQueueKindConcurrent: + actual_kind_string = "Concurrent queue" + self.assertTrue( + queue.GetKind() == kind, + "queue %s is expected to be a %s but it is actually a %s" % + (queue.GetName(), + expected_kind_string, + actual_kind_string)) + + def check_queues_threads_match_queue(self, queue): + for idx in range(0, queue.GetNumThreads()): + t = queue.GetThreadAtIndex(idx) + self.assertTrue( + t.IsValid(), "Queue %s's thread #%d must be valid" % + (queue.GetName(), idx)) + self.assertTrue( + t.GetQueueID() == queue.GetQueueID(), + "Queue %s has a QueueID of %d but its thread #%d has a QueueID of %d" % + (queue.GetName(), + queue.GetQueueID(), + idx, + t.GetQueueID())) + self.assertTrue( + t.GetQueueName() == queue.GetName(), + "Queue %s has a QueueName of %s but its thread #%d has a QueueName of %s" % + (queue.GetName(), + queue.GetName(), + idx, + t.GetQueueName())) + self.assertTrue( + t.GetQueue().GetQueueID() == queue.GetQueueID(), + "Thread #%d's Queue's QueueID of %d is not the same as the QueueID of its owning queue %d" % + (idx, + t.GetQueue().GetQueueID(), + queue.GetQueueID())) + + def queues(self): + """Test queues inspection SB APIs without libBacktraceRecording.""" + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + self.main_source_spec = lldb.SBFileSpec(self.main_source) + break1 = target.BreakpointCreateByName("stopper", 'a.out') + self.assertTrue(break1, VALID_BREAKPOINT) + process = target.LaunchSimple( + [], None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint 1.") + + self.inferior_process = process + + queue_submittor_1 = lldb.SBQueue() + queue_performer_1 = lldb.SBQueue() + queue_performer_2 = lldb.SBQueue() + queue_performer_3 = lldb.SBQueue() + for idx in range(0, process.GetNumQueues()): + q = process.GetQueueAtIndex(idx) + if q.GetName() == "com.apple.work_submittor_1": + queue_submittor_1 = q + if q.GetName() == "com.apple.work_performer_1": + queue_performer_1 = q + if q.GetName() == "com.apple.work_performer_2": + queue_performer_2 = q + if q.GetName() == "com.apple.work_performer_3": + queue_performer_3 = q + + self.assertTrue( + queue_submittor_1.IsValid() and queue_performer_1.IsValid() and queue_performer_2.IsValid() and queue_performer_3.IsValid(), + "Got all four expected queues: %s %s %s %s" % + (queue_submittor_1.IsValid(), + queue_performer_1.IsValid(), + queue_performer_2.IsValid(), + queue_performer_3.IsValid())) + + self.check_queue_for_valid_queue_id(queue_submittor_1) + self.check_queue_for_valid_queue_id(queue_performer_1) + self.check_queue_for_valid_queue_id(queue_performer_2) + self.check_queue_for_valid_queue_id(queue_performer_3) + + self.check_number_of_threads_owned_by_queue(queue_submittor_1, 1) + self.check_number_of_threads_owned_by_queue(queue_performer_1, 1) + self.check_number_of_threads_owned_by_queue(queue_performer_2, 1) + self.check_number_of_threads_owned_by_queue(queue_performer_3, 4) + + self.check_queue_kind(queue_submittor_1, lldb.eQueueKindSerial) + self.check_queue_kind(queue_performer_1, lldb.eQueueKindSerial) + self.check_queue_kind(queue_performer_2, lldb.eQueueKindSerial) + self.check_queue_kind(queue_performer_3, lldb.eQueueKindConcurrent) + + self.check_queues_threads_match_queue(queue_submittor_1) + self.check_queues_threads_match_queue(queue_performer_1) + self.check_queues_threads_match_queue(queue_performer_2) + self.check_queues_threads_match_queue(queue_performer_3) + + # We have threads running with all the different dispatch QoS service + # levels - find those threads and check that we can get the correct + # QoS name for each of them. + + user_initiated_thread = lldb.SBThread() + user_interactive_thread = lldb.SBThread() + utility_thread = lldb.SBThread() + unspecified_thread = lldb.SBThread() + background_thread = lldb.SBThread() + for th in process.threads: + if th.GetName() == "user initiated QoS": + user_initiated_thread = th + if th.GetName() == "user interactive QoS": + user_interactive_thread = th + if th.GetName() == "utility QoS": + utility_thread = th + if th.GetName() == "unspecified QoS": + unspecified_thread = th + if th.GetName() == "background QoS": + background_thread = th + + self.assertTrue( + user_initiated_thread.IsValid(), + "Found user initiated QoS thread") + self.assertTrue( + user_interactive_thread.IsValid(), + "Found user interactive QoS thread") + self.assertTrue(utility_thread.IsValid(), "Found utility QoS thread") + self.assertTrue( + unspecified_thread.IsValid(), + "Found unspecified QoS thread") + self.assertTrue( + background_thread.IsValid(), + "Found background QoS thread") + + stream = lldb.SBStream() + self.assertTrue( + user_initiated_thread.GetInfoItemByPathAsString( + "requested_qos.printable_name", + stream), + "Get QoS printable string for user initiated QoS thread") + self.assertTrue( + stream.GetData() == "User Initiated", + "user initiated QoS thread name is valid") + stream.Clear() + self.assertTrue( + user_interactive_thread.GetInfoItemByPathAsString( + "requested_qos.printable_name", + stream), + "Get QoS printable string for user interactive QoS thread") + self.assertTrue( + stream.GetData() == "User Interactive", + "user interactive QoS thread name is valid") + stream.Clear() + self.assertTrue( + utility_thread.GetInfoItemByPathAsString( + "requested_qos.printable_name", + stream), + "Get QoS printable string for utility QoS thread") + self.assertTrue( + stream.GetData() == "Utility", + "utility QoS thread name is valid") + stream.Clear() + self.assertTrue( + unspecified_thread.GetInfoItemByPathAsString( + "requested_qos.printable_name", + stream), + "Get QoS printable string for unspecified QoS thread") + qosName = stream.GetData() + self.assertTrue( + qosName == "User Initiated" or qosName == "Default", + "unspecified QoS thread name is valid") + stream.Clear() + self.assertTrue( + background_thread.GetInfoItemByPathAsString( + "requested_qos.printable_name", + stream), + "Get QoS printable string for background QoS thread") + self.assertTrue( + stream.GetData() == "Background", + "background QoS thread name is valid") + + @skipIfDarwin # rdar://50379398 + def queues_with_libBacktraceRecording(self): + """Test queues inspection SB APIs with libBacktraceRecording present.""" + exe = self.getBuildArtifact("a.out") + + if not os.path.isfile( + '/Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylib'): + self.skipTest( + "Skipped because libBacktraceRecording.dylib was present on the system.") + + if not os.path.isfile( + '/usr/lib/system/introspection/libdispatch.dylib'): + self.skipTest( + "Skipped because introspection libdispatch dylib is not present.") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + self.main_source_spec = lldb.SBFileSpec(self.main_source) + + break1 = target.BreakpointCreateByName("stopper", 'a.out') + self.assertTrue(break1, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + libbtr_path = "/Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylib" + if self.getArchitecture() in ['arm', 'arm64', 'arm64e', 'arm64_32', 'armv7', 'armv7k']: + libbtr_path = "/Developer/usr/lib/libBacktraceRecording.dylib" + + process = target.LaunchSimple( + [], + [ + 'DYLD_INSERT_LIBRARIES=%s' % (libbtr_path), + 'DYLD_LIBRARY_PATH=/usr/lib/system/introspection'], + self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint 1.") + + self.inferior_process = process + + libbtr_module_filespec = lldb.SBFileSpec("libBacktraceRecording.dylib") + libbtr_module = target.FindModule(libbtr_module_filespec) + if not libbtr_module.IsValid(): + self.skipTest( + "Skipped because libBacktraceRecording.dylib was not loaded into the process.") + + self.assertTrue( + process.GetNumQueues() >= 4, + "Found the correct number of queues.") + + queue_submittor_1 = lldb.SBQueue() + queue_performer_1 = lldb.SBQueue() + queue_performer_2 = lldb.SBQueue() + queue_performer_3 = lldb.SBQueue() + for idx in range(0, process.GetNumQueues()): + q = process.GetQueueAtIndex(idx) + if "LLDB_COMMAND_TRACE" in os.environ: + print("Queue with id %s has name %s" % (q.GetQueueID(), q.GetName())) + if q.GetName() == "com.apple.work_submittor_1": + queue_submittor_1 = q + if q.GetName() == "com.apple.work_performer_1": + queue_performer_1 = q + if q.GetName() == "com.apple.work_performer_2": + queue_performer_2 = q + if q.GetName() == "com.apple.work_performer_3": + queue_performer_3 = q + if q.GetName() == "com.apple.main-thread": + if q.GetNumThreads() == 0: + print("Cannot get thread <=> queue associations") + return + + self.assertTrue( + queue_submittor_1.IsValid() and queue_performer_1.IsValid() and queue_performer_2.IsValid() and queue_performer_3.IsValid(), + "Got all four expected queues: %s %s %s %s" % + (queue_submittor_1.IsValid(), + queue_performer_1.IsValid(), + queue_performer_2.IsValid(), + queue_performer_3.IsValid())) + + self.check_queue_for_valid_queue_id(queue_submittor_1) + self.check_queue_for_valid_queue_id(queue_performer_1) + self.check_queue_for_valid_queue_id(queue_performer_2) + self.check_queue_for_valid_queue_id(queue_performer_3) + + self.check_running_and_pending_items_on_queue(queue_submittor_1, 1, 0) + self.check_running_and_pending_items_on_queue(queue_performer_1, 1, 3) + self.check_running_and_pending_items_on_queue( + queue_performer_2, 1, 9999) + self.check_running_and_pending_items_on_queue(queue_performer_3, 4, 0) + + self.check_number_of_threads_owned_by_queue(queue_submittor_1, 1) + self.check_number_of_threads_owned_by_queue(queue_performer_1, 1) + self.check_number_of_threads_owned_by_queue(queue_performer_2, 1) + self.check_number_of_threads_owned_by_queue(queue_performer_3, 4) + + self.check_queue_kind(queue_submittor_1, lldb.eQueueKindSerial) + self.check_queue_kind(queue_performer_1, lldb.eQueueKindSerial) + self.check_queue_kind(queue_performer_2, lldb.eQueueKindSerial) + self.check_queue_kind(queue_performer_3, lldb.eQueueKindConcurrent) + + self.check_queues_threads_match_queue(queue_submittor_1) + self.check_queues_threads_match_queue(queue_performer_1) + self.check_queues_threads_match_queue(queue_performer_2) + self.check_queues_threads_match_queue(queue_performer_3) + + self.assertTrue(queue_performer_2.GetPendingItemAtIndex( + 0).IsValid(), "queue 2's pending item #0 is valid") + self.assertTrue(queue_performer_2.GetPendingItemAtIndex(0).GetAddress().GetSymbol( + ).GetName() == "doing_the_work_2", "queue 2's pending item #0 should be doing_the_work_2") + self.assertTrue( + queue_performer_2.GetNumPendingItems() == 9999, + "verify that queue 2 still has 9999 pending items") + self.assertTrue(queue_performer_2.GetPendingItemAtIndex( + 9998).IsValid(), "queue 2's pending item #9998 is valid") + self.assertTrue(queue_performer_2.GetPendingItemAtIndex(9998).GetAddress().GetSymbol( + ).GetName() == "doing_the_work_2", "queue 2's pending item #0 should be doing_the_work_2") + self.assertTrue(queue_performer_2.GetPendingItemAtIndex( + 9999).IsValid() == False, "queue 2's pending item #9999 is invalid") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/main.c new file mode 100644 index 00000000000..3978b92bff1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/queues/main.c @@ -0,0 +1,151 @@ +#include <stdatomic.h> +#include <string.h> +#include <unistd.h> +#include <dispatch/dispatch.h> +#include <pthread.h> + +atomic_int finished_enqueueing_work = 0; +atomic_int thread_count = 0; + +void +doing_the_work_1(void *in) +{ + // This is only counted once because the first job in the queue + // starves all the others. + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (1); +} + +void +submit_work_1a(void *in) +{ + dispatch_queue_t *work_performer_1 = (dispatch_queue_t*) in; + dispatch_async_f (*work_performer_1, NULL, doing_the_work_1); + dispatch_async_f (*work_performer_1, NULL, doing_the_work_1); +} + +void +submit_work_1b(void *in) +{ + dispatch_queue_t *work_performer_1 = (dispatch_queue_t*) in; + dispatch_async_f (*work_performer_1, NULL, doing_the_work_1); + dispatch_async_f (*work_performer_1, NULL, doing_the_work_1); + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (1); +} + +void +doing_the_work_2(void *in) +{ + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (1); +} + +void +submit_work_2(void *in) +{ + dispatch_queue_t *work_performer_2 = (dispatch_queue_t*) in; + int i = 0; + while (i++ < 5000) + { + dispatch_async_f (*work_performer_2, NULL, doing_the_work_2); + dispatch_async_f (*work_performer_2, NULL, doing_the_work_2); + } + atomic_fetch_add(&finished_enqueueing_work, 1); +} + + +void +doing_the_work_3(void *in) +{ + // This counts four times, since the queue is marked as CONCURRENT. + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (1); +} + +void +submit_work_3(void *in) +{ + dispatch_queue_t *work_performer_3 = (dispatch_queue_t*) in; + dispatch_async_f (*work_performer_3, NULL, doing_the_work_3); + dispatch_async_f (*work_performer_3, NULL, doing_the_work_3); + dispatch_async_f (*work_performer_3, NULL, doing_the_work_3); + dispatch_async_f (*work_performer_3, NULL, doing_the_work_3); +} + + +void +stopper () +{ + while (1) + sleep (1); +} + + +int main (int argc, const char **argv) +{ + dispatch_queue_t work_submittor_1 = dispatch_queue_create ("com.apple.work_submittor_1", DISPATCH_QUEUE_SERIAL); + dispatch_queue_t work_submittor_2 = dispatch_queue_create ("com.apple.work_submittor_and_quit_2", DISPATCH_QUEUE_SERIAL); + dispatch_queue_t work_submittor_3 = dispatch_queue_create ("com.apple.work_submittor_3", DISPATCH_QUEUE_SERIAL); + + dispatch_queue_t work_performer_1 = dispatch_queue_create ("com.apple.work_performer_1", DISPATCH_QUEUE_SERIAL); + dispatch_queue_t work_performer_2 = dispatch_queue_create ("com.apple.work_performer_2", DISPATCH_QUEUE_SERIAL); + + dispatch_queue_t work_performer_3 = dispatch_queue_create ("com.apple.work_performer_3", DISPATCH_QUEUE_CONCURRENT); + + dispatch_async_f (work_submittor_1, (void*) &work_performer_1, submit_work_1a); + dispatch_async_f (work_submittor_1, (void*) &work_performer_1, submit_work_1b); + + dispatch_async_f (work_submittor_2, (void*) &work_performer_2, submit_work_2); + + dispatch_async_f (work_submittor_3, (void*) &work_performer_3, submit_work_3); + + + // Spin up threads with each of the different libdispatch QoS values. + dispatch_async (dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ + pthread_setname_np ("user initiated QoS"); + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (10); + }); + dispatch_async (dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{ + pthread_setname_np ("user interactive QoS"); + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (10); + }); + dispatch_async (dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + pthread_setname_np ("default QoS"); + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (10); + }); + dispatch_async (dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ + pthread_setname_np ("utility QoS"); + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (10); + }); + dispatch_async (dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ + pthread_setname_np ("background QoS"); + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (10); + }); + dispatch_async (dispatch_get_global_queue(QOS_CLASS_UNSPECIFIED, 0), ^{ + pthread_setname_np ("unspecified QoS"); + atomic_fetch_add(&thread_count, 1); + while (1) + sleep (10); + }); + + // Unfortunately there is no pthread_barrier on darwin. + while ((atomic_load(&thread_count) < 13) || (finished_enqueueing_work == 0)) + sleep (1); + + stopper (); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/TestSafeFuncCalls.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/TestSafeFuncCalls.py new file mode 100644 index 00000000000..fe6d748e58e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/TestSafeFuncCalls.py @@ -0,0 +1,70 @@ +"""Test function call thread safety.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestSafeFuncCalls(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test function call thread safety.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + self.main_source_spec = lldb.SBFileSpec(self.main_source) + break1 = target.BreakpointCreateByName("stopper", 'a.out') + self.assertTrue(break1, VALID_BREAKPOINT) + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint 1.") + + self.check_number_of_threads(process) + + main_thread = lldb.SBThread() + select_thread = lldb.SBThread() + for idx in range(0, process.GetNumThreads()): + t = process.GetThreadAtIndex(idx) + if t.GetName() == "main thread": + main_thread = t + if t.GetName() == "select thread": + select_thread = t + + self.assertTrue( + main_thread.IsValid() and select_thread.IsValid(), + "Got both expected threads") + + self.safe_to_call_func_on_main_thread(main_thread) + self.safe_to_call_func_on_select_thread(select_thread) + + def check_number_of_threads(self, process): + self.assertTrue( + process.GetNumThreads() == 2, + "Check that the process has two threads when sitting at the stopper() breakpoint") + + def safe_to_call_func_on_main_thread(self, main_thread): + self.assertTrue(main_thread.SafeToCallFunctions(), + "It is safe to call functions on the main thread") + + def safe_to_call_func_on_select_thread(self, select_thread): + self.assertTrue( + select_thread.SafeToCallFunctions() == False, + "It is not safe to call functions on the select thread") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/main.c new file mode 100644 index 00000000000..58650087628 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/safe-to-func-call/main.c @@ -0,0 +1,31 @@ +#include <sys/time.h> // work around module map issue with iOS sdk, <rdar://problem/35159346> +#include <sys/select.h> +#include <stdio.h> +#include <pthread.h> +#include <unistd.h> + +void * +select_thread (void *in) +{ + pthread_setname_np ("select thread"); + fd_set fdset; + FD_SET (STDIN_FILENO, &fdset); + while (1) + select (2, &fdset, NULL, NULL, NULL); + return NULL; +} + +void stopper () +{ + while (1) + sleep(1); // break here +} + +int main () +{ + pthread_setname_np ("main thread"); + pthread_t other_thread; + pthread_create (&other_thread, NULL, select_thread, NULL); + sleep (1); + stopper(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/TestInterruptThreadNames.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/TestInterruptThreadNames.py new file mode 100644 index 00000000000..2a2768195d4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/TestInterruptThreadNames.py @@ -0,0 +1,133 @@ +"""Test that we get thread names when interrupting a process.""" + + +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestInterruptThreadNames(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test that we get thread names when interrupting a process.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + launch_info = lldb.SBLaunchInfo(None) + error = lldb.SBError() + self.dbg.SetAsync(True) + process = target.Launch(launch_info, error) + self.assertTrue(process, PROCESS_IS_VALID) + + listener = self.dbg.GetListener() + broadcaster = process.GetBroadcaster() + rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged) + self.assertTrue(rc != 0, "Unable to add listener to process") + self.assertTrue(self.wait_for_running(process, listener), "Check that process is up and running") + + inferior_set_up = self.wait_until_program_setup_complete(process, listener) + + self.assertTrue(inferior_set_up.IsValid() and inferior_set_up.GetValueAsSigned() == 1, "Check that the program was able to create its threads within the allotted time") + + self.check_number_of_threads(process) + + main_thread = lldb.SBThread() + second_thread = lldb.SBThread() + third_thread = lldb.SBThread() + for idx in range(0, process.GetNumThreads()): + t = process.GetThreadAtIndex(idx) + if t.GetName() == "main thread": + main_thread = t + if t.GetName() == "second thread": + second_thread = t + if t.GetName() == "third thread": + third_thread = t + + self.check_expected_threads_present(main_thread, second_thread, third_thread) + + process.Kill() + + + # The process will set a global variable 'threads_up_and_running' to 1 when + # it has has completed its setup. Sleep for one second, pause the program, + # check to see if the global has that value, and continue if it does not. + def wait_until_program_setup_complete(self, process, listener): + inferior_set_up = lldb.SBValue() + retry = 5 + while retry > 0: + arch = self.getArchitecture() + # when running the testsuite against a remote arm device, it may take + # a little longer for the process to start up. Use a "can't possibly take + # longer than this" value. + if arch == 'arm64' or arch == 'armv7': + time.sleep(10) + else: + time.sleep(1) + process.SendAsyncInterrupt() + self.assertTrue(self.wait_for_stop(process, listener), "Check that process is paused") + inferior_set_up = process.GetTarget().CreateValueFromExpression("threads_up_and_running", "threads_up_and_running") + if inferior_set_up.IsValid() and inferior_set_up.GetValueAsSigned() == 1: + retry = 0 + else: + process.Continue() + retry = retry - 1 + return inferior_set_up + + # Listen to the process events until we get an event saying that the process is + # running. Retry up to five times in case we get other events that are not + # what we're looking for. + def wait_for_running(self, process, listener): + retry_count = 5 + if process.GetState() == lldb.eStateRunning: + return True + + while retry_count > 0: + event = lldb.SBEvent() + listener.WaitForEvent(2, event) + if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged: + if process.GetState() == lldb.eStateRunning: + return True + retry_count = retry_count - 1 + + return False + + # Listen to the process events until we get an event saying the process is + # stopped. Retry up to five times in case we get other events that we are + # not looking for. + def wait_for_stop(self, process, listener): + retry_count = 5 + if process.GetState() == lldb.eStateStopped or process.GetState() == lldb.eStateCrashed or process.GetState() == lldb.eStateDetached or process.GetState() == lldb.eStateExited: + return True + + while retry_count > 0: + event = lldb.SBEvent() + listener.WaitForEvent(2, event) + if event.GetType() == lldb.SBProcess.eBroadcastBitStateChanged: + if process.GetState() == lldb.eStateStopped or process.GetState() == lldb.eStateCrashed or process.GetState() == lldb.eStateDetached or process.GetState() == lldb.eStateExited: + return True + if process.GetState() == lldb.eStateCrashed or process.GetState() == lldb.eStateDetached or process.GetState() == lldb.eStateExited: + return False + retry_count = retry_count - 1 + + return False + + + + def check_number_of_threads(self, process): + self.assertTrue( + process.GetNumThreads() == 3, + "Check that the process has three threads when sitting at the stopper() breakpoint") + + def check_expected_threads_present(self, main_thread, second_thread, third_thread): + self.assertTrue( + main_thread.IsValid() and second_thread.IsValid() and third_thread.IsValid(), + "Got all three expected threads") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/main.c new file mode 100644 index 00000000000..6834f064151 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/thread-names/main.c @@ -0,0 +1,36 @@ +#include <stdio.h> +#include <pthread.h> +#include <unistd.h> + +int threads_up_and_running = 0; + +void * +second_thread (void *in) +{ + pthread_setname_np ("second thread"); + while (1) + sleep (1); + return NULL; +} + +void * +third_thread (void *in) +{ + pthread_setname_np ("third thread"); + while (1) + sleep (1); + return NULL; +} + +int main () +{ + pthread_setname_np ("main thread"); + pthread_t other_thread; + pthread_create (&other_thread, NULL, second_thread, NULL); + pthread_create (&other_thread, NULL, third_thread, NULL); + + threads_up_and_running = 1; + + while (1) + sleep (1); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/Makefile new file mode 100644 index 00000000000..efdeb1fd131 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/Makefile @@ -0,0 +1,23 @@ +EXE := testit + +include Makefile.rules + +all: testit + +testit: testit.x86_64h testit.x86_64 + lipo -create -o testit $^ + +testit.x86_64h: testit.x86_64h.o + $(CC) -arch x86_64h -o testit.x86_64h $< + +testit.x86_64: testit.x86_64.o + $(CC) -arch x86_64 -o testit.x86_64 $< + +testit.x86_64h.o: main.c + $(CC) -g -O0 -arch x86_64h -c -o testit.x86_64h.o $< + +testit.x86_64.o: main.c + $(CC) -g -O0 -arch x86_64 -c -o testit.x86_64.o $< + +clean:: + rm -rf $(wildcard testit* *~) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/TestUniversal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/TestUniversal.py new file mode 100644 index 00000000000..ebcdee84f64 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/TestUniversal.py @@ -0,0 +1,162 @@ +"""Test aspects of lldb commands on universal binaries.""" + + + +import unittest2 +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +def haswellOrLater(): + features = subprocess.check_output(["sysctl", "machdep.cpu"]) + return "AVX2" in features.split() + +class UniversalTestCase(TestBase): + + NO_DEBUG_INFO_TESTCASE = True + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + @add_test_categories(['pyapi']) + @skipUnlessDarwin + @unittest2.skipUnless(hasattr(os, "uname") and os.uname()[4] in + ['x86_64'], "requires x86_64") + @skipIfDarwinEmbedded # this test file assumes we're targetting an x86 system + def test_sbdebugger_create_target_with_file_and_target_triple(self): + """Test the SBDebugger.CreateTargetWithFileAndTargetTriple() API.""" + # Invoke the default build rule. + self.build() + + # Note that "testit" is a universal binary. + exe = self.getBuildArtifact("testit") + + # Create a target by the debugger. + target = self.dbg.CreateTargetWithFileAndTargetTriple( + exe, "x86_64-apple-macosx") + self.assertTrue(target, VALID_TARGET) + self.expect("image list -A -b", substrs=["x86_64 testit"]) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + @skipUnlessDarwin + @unittest2.skipUnless(hasattr(os, "uname") and os.uname()[4] in + ['x86_64'], "requires x86_64") + @skipIfDarwinEmbedded # this test file assumes we're targetting an x86 system + def test_process_launch_for_universal(self): + """Test process launch of a universal binary.""" + from lldbsuite.test.lldbutil import print_registers + + if not haswellOrLater(): + return + + # Invoke the default build rule. + self.build() + + # Note that "testit" is a universal binary. + exe = self.getBuildArtifact("testit") + + # By default, x86_64 is assumed if no architecture is specified. + self.expect("file " + exe, CURRENT_EXECUTABLE_SET, + startstr="Current executable set to ", + substrs=["testit' (x86_64h)."]) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + # We should be able to launch the x86_64h executable. + self.runCmd("run", RUN_SUCCEEDED) + + # Check whether we have a x86_64h process launched. + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + self.expect("image list -A -b", substrs=["x86_64h testit"]) + self.runCmd("continue") + + # Now specify x86_64 as the architecture for "testit". + self.expect("file -a x86_64 " + exe, CURRENT_EXECUTABLE_SET, + startstr="Current executable set to ", + substrs=["testit' (x86_64)."]) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + # We should be able to launch the x86_64 executable as well. + self.runCmd("run", RUN_SUCCEEDED) + + # Check whether we have a x86_64 process launched. + + # FIXME: This wrong. We are expecting x86_64, but spawning a + # new process currently doesn't allow specifying a *sub*-architecture. + # <rdar://problem/46101466> + self.expect("image list -A -b", substrs=["x86_64h testit"]) + self.runCmd("continue") + + @skipUnlessDarwin + @unittest2.skipUnless(hasattr(os, "uname") and os.uname()[4] in + ['x86_64'], "requires x86_64") + @skipIfDarwinEmbedded # this test file assumes we're targetting an x86 system + def test_process_attach_with_wrong_arch(self): + """Test that when we attach to a binary from the wrong fork of + a universal binary, we fix up the ABI correctly.""" + if not haswellOrLater(): + return + + # Now keep the architecture at x86_64, but switch the binary + # we launch to x86_64h, and make sure on attach we switch to + # the correct architecture. + + # Invoke the default build rule. + self.build() + + # Note that "testit" is a universal binary. + exe = self.getBuildArtifact("testit") + + # Create a target by the debugger. + target = self.dbg.CreateTargetWithFileAndTargetTriple( + exe, "x86_64-apple-macosx") + self.assertTrue(target, VALID_TARGET) + self.expect("image list -A -b", substrs=["x86_64 testit"]) + + bkpt = target.BreakpointCreateBySourceRegex( + "sleep", lldb.SBFileSpec("main.c")) + self.assertTrue(bkpt.IsValid(), "Valid breakpoint") + self.assertTrue( + bkpt.GetNumLocations() >= 1, + "Our main breakpoint has locations.") + + popen = self.spawnSubprocess(exe, ["keep_waiting"]) + self.addTearDownHook(self.cleanupSubprocesses) + + error = lldb.SBError() + empty_listener = lldb.SBListener() + process = target.AttachToProcessWithID( + empty_listener, popen.pid, error) + self.assertTrue(error.Success(), "Attached to process.") + + self.expect("image list -A -b", substrs=["x86_64h testit"]) + + # It may seem odd to check the number of frames, but the bug + # that motivated this test was that we eventually fixed the + # architecture, but we left the ABI set to the original value. + # In that case, if you asked the process for its architecture, + # it would look right, but since the ABI was wrong, + # backtracing failed. + + threads = lldbutil.continue_to_breakpoint(process, bkpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + self.assertTrue( + thread.GetNumFrames() > 1, + "We were able to backtrace.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/main.c new file mode 100644 index 00000000000..3edab51b1f6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/universal/main.c @@ -0,0 +1,21 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +void +call_me() +{ + sleep(1); +} + +int +main (int argc, char **argv) +{ + printf ("Hello there!\n"); // Set break point at this line. + if (argc == 2 && strcmp(argv[1], "keep_waiting") == 0) + while (1) + { + call_me(); + } + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/version_zero/TestGetVersionZeroVersion.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/version_zero/TestGetVersionZeroVersion.py new file mode 100644 index 00000000000..f7e4da73dda --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/version_zero/TestGetVersionZeroVersion.py @@ -0,0 +1,39 @@ +""" +Read in a library with a version number of 0.0.0, make sure we produce a good version. +""" + + + +import lldb +from lldbsuite.test import decorators +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class TestGetVersionForZero(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 test_get_version_zero(self): + """Read in a library with a version of 0.0.0. Test SBModule::GetVersion""" + self.yaml2obj("libDylib.dylib.yaml", self.getBuildArtifact("libDylib.dylib")) + self.do_test() + + def do_test(self): + lib_name = "libDylib.dylib" + target = lldbutil.run_to_breakpoint_make_target(self, exe_name=lib_name) + module = target.FindModule(lldb.SBFileSpec(lib_name)) + self.assertTrue(module.IsValid(), "Didn't find the libDylib.dylib module") + # For now the actual version numbers are wrong for a library of 0.0.0 + # but the previous code would crash iterating over the resultant + # list. So we are testing that that doesn't happen. + did_iterate = False + for elem in module.GetVersion(): + did_iterate = True + self.assertTrue(did_iterate, "Didn't get into the GetVersion loop") + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/version_zero/libDylib.dylib.yaml b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/version_zero/libDylib.dylib.yaml new file mode 100644 index 00000000000..a672f49fb4a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/macosx/version_zero/libDylib.dylib.yaml @@ -0,0 +1,220 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x00000006 + ncmds: 12 + sizeofcmds: 672 + flags: 0x00100085 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __TEXT + vmaddr: 0 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 5 + initprot: 5 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000000000FA0 + size: 11 + offset: 0x00000FA0 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000000000FAC + size: 72 + offset: 0x00000FAC + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4096 + vmsize: 4096 + fileoff: 4096 + filesize: 528 + maxprot: 1 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_ID_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 1 + current_version: 0 + compatibility_version: 0 + PayloadString: '@executable_path/libDylib.dylib' + ZeroPadBytes: 1 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 0 + rebase_size: 0 + bind_off: 0 + bind_size: 0 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 0 + lazy_bind_size: 0 + export_off: 4096 + export_size: 16 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 4120 + nsyms: 10 + stroff: 4280 + strsize: 344 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 8 + iextdefsym: 8 + nextdefsym: 1 + iundefsym: 9 + nundefsym: 1 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_UUID + cmdsize: 24 + uuid: 5F76D8E3-7EA5-3092-8A9D-0D0E36429550 + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 659200 + sdk: 659200 + ntools: 1 + Tools: + - tool: 3 + version: 33227776 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 83427328 + compatibility_version: 65536 + PayloadString: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 4112 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 4120 + datasize: 0 +LinkEditData: + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + Children: + - TerminalSize: 3 + NodeOffset: 9 + Name: _func + Flags: 0x0000000000000000 + Address: 0x0000000000000FA0 + Other: 0x0000000000000000 + ImportName: '' + NameList: + - n_strx: 25 + n_type: 0x64 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 148 + n_type: 0x64 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 156 + n_type: 0x66 + n_sect: 3 + n_desc: 1 + n_value: 1553735575 + - n_strx: 1 + n_type: 0x2E + n_sect: 1 + n_desc: 0 + n_value: 4000 + - n_strx: 332 + n_type: 0x24 + n_sect: 1 + n_desc: 0 + n_value: 4000 + - n_strx: 1 + n_type: 0x24 + n_sect: 0 + n_desc: 0 + n_value: 11 + - n_strx: 1 + n_type: 0x4E + n_sect: 1 + n_desc: 0 + n_value: 11 + - n_strx: 1 + n_type: 0x64 + n_sect: 1 + n_desc: 0 + n_value: 0 + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4000 + - n_strx: 8 + n_type: 0x01 + n_sect: 0 + n_desc: 256 + n_value: 0 + StringTable: + - ' ' + - _func + - dyld_stub_binder + - '/Volumes/ThePlayground/Users/jingham/Work/LLDB/llvm-dot-org/lldb-clean/packages/Python/lldbsuite/test/macosx/version_zero/' + - dylib.c + - '/Volumes/ThePlayground/Users/jingham/Work/LLDB/llvm-dot-org/lldb-clean/test/lldb-test-build.noindex/macosx/version_zero/TestGetVersionZeroVersion.test_get_version_zero/dylib.o' + - _func + - '' + - '' + - '' + - '' + - '' + - '' +... |