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)))
def is_compiler_with_address_sanitizer(self): compiler_path = self.getCompiler() compiler = os.path.basename(compiler_path) f = tempfile.NamedTemporaryFile() if lldbplatformutil.getPlatform() == 'windows': return "ASAN tests not compatible with 'windows'" cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name) if os.popen(cmd).close() is not None: return None # The compiler cannot compile at all, let's *not* skip the test cmd = "echo 'int main() {}' | %s -fsanitize=address -x c -o %s -" % (compiler_path, f.name) if os.popen(cmd).close() is not None: return "Compiler cannot compile with -fsanitize=address" return None
def is_compiler_clang_with_thread_sanitizer(self): compiler_path = self.getCompiler() compiler = os.path.basename(compiler_path) if not compiler.startswith("clang"): return "Test requires clang as compiler" if lldbplatformutil.getPlatform() == 'windows': return "TSAN tests not compatible with 'windows'" # rdar://28659145 - TSAN tests don't look like they're supported on i386 if self.getArchitecture() == 'i386' and platform.system() == 'Darwin': return "TSAN tests not compatible with i386 targets" f = tempfile.NamedTemporaryFile() cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name) if os.popen(cmd).close() is not None: return None # The compiler cannot compile at all, let's *not* skip the test cmd = "echo 'int main() {}' | %s -fsanitize=thread -x c -o %s -" % (compiler_path, f.name) if os.popen(cmd).close() is not None: return "Compiler cannot compile with -fsanitize=thread" return None
def is_compiler_clang_with_thread_sanitizer(self): compiler_path = self.getCompiler() compiler = os.path.basename(compiler_path) if not compiler.startswith("clang"): return "Test requires clang as compiler" if lldbplatformutil.getPlatform() == 'windows': return "TSAN tests not compatible with 'windows'" # rdar://28659145 - TSAN tests don't look like they're supported on i386 if self.getArchitecture() == 'i386' and platform.system() == 'Darwin': return "TSAN tests not compatible with i386 targets" f = tempfile.NamedTemporaryFile() cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name) if os.popen(cmd).close() is not None: return None # The compiler cannot compile at all, let's *not* skip the test cmd = "echo 'int main() {}' | %s -fsanitize=thread -x c -o %s -" % ( compiler_path, f.name) if os.popen(cmd).close() is not None: return "Compiler cannot compile with -fsanitize=thread" return None
def canRunLibcxxTests(): from lldbsuite.test import lldbplatformutil platform = lldbplatformutil.getPlatform() if lldbplatformutil.target_is_android() or lldbplatformutil.platformIsDarwin(): return True, "libc++ always present" if platform == "linux": if os.path.isdir("/usr/include/c++/v1"): return True, "Headers found, let's hope they work" with tempfile.NamedTemporaryFile() as f: cmd = [configuration.compiler, "-xc++", "-stdlib=libc++", "-o", f.name, "-"] p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) _, stderr = p.communicate("#include <algorithm>\nint main() {}") if not p.returncode: return True, "Compiling with -stdlib=libc++ works" return False, "Compiling with -stdlib=libc++ fails with the error: %s" % stderr return False, "Don't know how to build with libc++ on %s" % platform
def canRunWatchpointTests(): from lldbsuite.test import lldbplatformutil platform = lldbplatformutil.getPlatform() if platform == "netbsd": if os.geteuid() == 0: return True, "root can always write dbregs" try: output = subprocess.check_output(["/sbin/sysctl", "-n", "security.models.extensions.user_set_dbregs"]).decode().strip() if output == "1": return True, "security.models.extensions.user_set_dbregs enabled" except subprocess.CalledProcessError: pass return False, "security.models.extensions.user_set_dbregs disabled" elif platform == "freebsd" and configuration.arch == "aarch64": import lldb if lldb.SBPlatform.GetHostPlatform().GetOSMajorVersion() < 13: return False, "Watchpoint support on arm64 requires FreeBSD 13.0" return True, "watchpoint support available"
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)))
def is_compiler_with_address_sanitizer(self): # Also don't run tests that use address sanitizer inside an # address-sanitized LLDB. The tests don't support that # configuration. if is_running_under_asan(): return "Address sanitizer tests are disabled when runing under ASAN" compiler_path = self.getCompiler() compiler = os.path.basename(compiler_path) f = tempfile.NamedTemporaryFile() if lldbplatformutil.getPlatform() == 'windows': return "ASAN tests not compatible with 'windows'" cmd = "echo 'int main() {}' | %s -x c -o %s -" % (compiler_path, f.name) if os.popen(cmd).close() is not None: return None # The compiler cannot compile at all, let's *not* skip the test cmd = "echo 'int main() {}' | %s -fsanitize=address -x c -o %s -" % ( compiler_path, f.name) if os.popen(cmd).close() is not None: return "Compiler cannot compile with -fsanitize=address" return None
def checkForkVForkSupport(): from lldbsuite.test import lldbplatformutil platform = lldbplatformutil.getPlatform() if platform not in ["freebsd", "linux", "netbsd"]: configuration.skip_categories.append("fork")
def skipUnlessPlatform(oslist): """Decorate the item to skip tests unless running on one of the listed platforms.""" # This decorator cannot be ported to `skipIf` yet because it is used on entire # classes, which `skipIf` explicitly forbids. return unittest2.skipUnless(lldbplatformutil.getPlatform() in oslist, "requires one of %s" % (", ".join(oslist)))
def testAvailability(self): platform_name = lldbplatformutil.getPlatform() os_name = getOSName(platform_name) platform = lldb.selected_platform major = platform.GetOSMajorVersion() minor = platform.GetOSMinorVersion() version = '%d.%d' % (major, minor) program = """ @available(%s %s, *) func f() {} // --------------------------------------------------------------------- // Method context. // --------------------------------------------------------------------- class C1 { func method() { print("in method") // break_1 } } C1().method() // break_0 // --------------------------------------------------------------------- // Generic method context. // --------------------------------------------------------------------- class C2 { func method<T>(_ t: T) { print("in method") // break_2 } } C2().method(0) // --------------------------------------------------------------------- // Method in generic class context. // --------------------------------------------------------------------- class C3<T> { func method() { print("in method") // break_3 } } C3<Int>().method() // --------------------------------------------------------------------- // Generic method in generic class context. // --------------------------------------------------------------------- class C4<U> { func method<V>(_ v: V) { print("in method") // break_4 } } C4<Int>().method(0) // --------------------------------------------------------------------- // Function context. // --------------------------------------------------------------------- func f1() { print("in function") // break_5 } f1() // --------------------------------------------------------------------- // Generic function context. // --------------------------------------------------------------------- func f2<T>(_ t: T) { print("in function") // break_6 } f2(0) // --------------------------------------------------------------------- // Top-level context. // --------------------------------------------------------------------- print("in top_level") // break_7 """ with open(self.getBuildArtifact("main.swift"), 'w') as main: main.write(program % (os_name, version)) self.build(dictionary={ 'TRIPLE': getTriple(platform_name, getOlderVersion(major, minor)) }) source_spec = lldb.SBFileSpec("main.swift") (target, process, thread, brk0) = \ lldbutil.run_to_source_breakpoint(self, "break_0", source_spec) # Create breakpoints. breakpoints = [] for i in range(1, 8): breakpoints.append( target.BreakpointCreateBySourceRegex( 'break_%d' % i, lldb.SBFileSpec("main.swift"))) self.assertTrue( breakpoints[-1] and breakpoints[-1].GetNumLocations() >= 1, VALID_BREAKPOINT) for breakpoint in breakpoints: threads = lldbutil.continue_to_breakpoint(process, breakpoint) self.runCmd("expr -d no-run-target -- f()", msg="can call")
def is_running_rosetta(self): if lldbplatformutil.getPlatform() in ['darwin', 'macosx']: if (platform.uname()[5] == "arm") and (self.getArchitecture() == "x86_64"): return "skipped under Rosetta" return None
def is_running_rosetta(self): if not lldbplatformutil.getPlatform() in ['darwin', 'macosx']: return False return platform.uname()[5] == "arm" and self.getArchitecture( ) == "x86_64"
def run_suite(): # On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults # does not exist before proceeding to running the test suite. if sys.platform.startswith("darwin"): checkDsymForUUIDIsNotOn() # Start the actions by first parsing the options while setting up the test # directories, followed by setting up the search paths for lldb utilities; # then, we walk the directory trees and collect the tests into our test suite. # parseOptionsAndInitTestdirs() # Print a stack trace if the test hangs or is passed SIGTERM. registerFaulthandler() setupSysPath() import lldbconfig if configuration.capture_path or configuration.replay_path: lldbconfig.INITIALIZE = False import lldb if configuration.capture_path: lldb.SBReproducer.Capture(configuration.capture_path) lldb.SBReproducer.SetAutoGenerate(True) elif configuration.replay_path: lldb.SBReproducer.PassiveReplay(configuration.replay_path) if not lldbconfig.INITIALIZE: lldb.SBDebugger.Initialize() # Use host platform by default. lldb.selected_platform = lldb.SBPlatform.GetHostPlatform() # Now we can also import lldbutil from lldbsuite.test import lldbutil if configuration.lldb_platform_name: print("Setting up remote platform '%s'" % (configuration.lldb_platform_name)) lldb.remote_platform = lldb.SBPlatform( configuration.lldb_platform_name) if not lldb.remote_platform.IsValid(): print("error: unable to create the LLDB platform named '%s'." % (configuration.lldb_platform_name)) exitTestSuite(1) if configuration.lldb_platform_url: # We must connect to a remote platform if a LLDB platform URL was # specified print("Connecting to remote platform '%s' at '%s'..." % (configuration.lldb_platform_name, configuration.lldb_platform_url)) platform_connect_options = lldb.SBPlatformConnectOptions( configuration.lldb_platform_url) err = lldb.remote_platform.ConnectRemote(platform_connect_options) if err.Success(): print("Connected.") else: print( "error: failed to connect to remote platform using URL '%s': %s" % (configuration.lldb_platform_url, err)) exitTestSuite(1) else: configuration.lldb_platform_url = None if configuration.lldb_platform_working_dir: print("Setting remote platform working directory to '%s'..." % (configuration.lldb_platform_working_dir)) error = lldb.remote_platform.MakeDirectory( configuration.lldb_platform_working_dir, 448) # 448 = 0o700 if error.Fail(): raise Exception("making remote directory '%s': %s" % (configuration.lldb_platform_working_dir, error)) if not lldb.remote_platform.SetWorkingDirectory( configuration.lldb_platform_working_dir): raise Exception("failed to set working directory '%s'" % configuration.lldb_platform_working_dir) lldb.selected_platform = lldb.remote_platform else: lldb.remote_platform = None configuration.lldb_platform_working_dir = None configuration.lldb_platform_url = None # Set up the working directory. # Note that it's not dotest's job to clean this directory. lldbutil.mkdir_p(configuration.test_build_dir) from . import lldbplatformutil target_platform = lldbplatformutil.getPlatform() checkLibcxxSupport() checkLibstdcxxSupport() checkWatchpointSupport() checkDebugInfoSupport() checkDebugServerSupport() checkObjcSupport() for testdir in configuration.testdirs: for (dirpath, dirnames, filenames) in os.walk(testdir): visit('Test', dirpath, filenames) # # Now that we have loaded all the test cases, run the whole test suite. # # Install the control-c handler. unittest2.signals.installHandler() # # Invoke the default TextTestRunner to run the test suite # checkCompiler() if configuration.verbose: print("compiler=%s" % configuration.compiler) # Iterating over all possible architecture and compiler combinations. configString = "arch=%s compiler=%s" % (configuration.arch, configuration.compiler) # Output the configuration. if configuration.verbose: sys.stderr.write("\nConfiguration: " + configString + "\n") # First, write out the number of collected test cases. if configuration.verbose: sys.stderr.write(configuration.separator + "\n") sys.stderr.write( "Collected %d test%s\n\n" % (configuration.suite.countTestCases(), configuration.suite.countTestCases() != 1 and "s" or "")) if configuration.suite.countTestCases() == 0: logging.error("did not discover any matching tests") exitTestSuite(1) # Invoke the test runner. if configuration.count == 1: result = unittest2.TextTestRunner( stream=sys.stderr, verbosity=configuration.verbose, resultclass=test_result.LLDBTestResult).run(configuration.suite) else: # We are invoking the same test suite more than once. In this case, # mark __ignore_singleton__ flag as True so the signleton pattern is # not enforced. test_result.LLDBTestResult.__ignore_singleton__ = True for i in range(configuration.count): result = unittest2.TextTestRunner( stream=sys.stderr, verbosity=configuration.verbose, resultclass=test_result.LLDBTestResult).run( configuration.suite) configuration.failed = not result.wasSuccessful() if configuration.sdir_has_content and configuration.verbose: sys.stderr.write( "Session logs for test failures/errors/unexpected successes" " can be found in the test build directory\n") if configuration.use_categories and len( configuration.failures_per_category) > 0: sys.stderr.write("Failures per category:\n") for category in configuration.failures_per_category: sys.stderr.write( "%s - %d\n" % (category, configuration.failures_per_category[category])) # Exiting. exitTestSuite(configuration.failed)