|
| 1 | +# TestSwiftStaticLinkingMacOS.py |
| 2 | +# |
| 3 | +# This source file is part of the Swift.org open source project |
| 4 | +# |
| 5 | +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors |
| 6 | +# Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +# |
| 8 | +# See http://swift.org/LICENSE.txt for license information |
| 9 | +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| 10 | +# |
| 11 | +# ------------------------------------------------------------------------------ |
| 12 | +""" |
| 13 | +Test that macOS can statically link two separately-compiled Swift modules |
| 14 | +with one Objective-C module, link them through the clang driver, and still |
| 15 | +access debug info for each of the Swift modules. |
| 16 | +""" |
| 17 | +from __future__ import print_function |
| 18 | + |
| 19 | + |
| 20 | +# System imports |
| 21 | +import os |
| 22 | +import commands |
| 23 | + |
| 24 | +# Third-party imports |
| 25 | + |
| 26 | +# LLDB imports |
| 27 | +import lldb |
| 28 | +from lldbsuite.test.lldbtest import TestBase |
| 29 | +from lldbsuite.test import decorators, lldbtest, lldbutil |
| 30 | + |
| 31 | + |
| 32 | +class SwiftStaticLinkingMacOSTestCase(TestBase): |
| 33 | + |
| 34 | + mydir = TestBase.compute_mydir(__file__) |
| 35 | + |
| 36 | + NO_DEBUG_INFO_TESTCASE = True |
| 37 | + |
| 38 | + def expect_self_var_available_at_breakpoint( |
| 39 | + self, process, breakpoint, module_name): |
| 40 | + # Frame #0 should be at the given breakpoint |
| 41 | + threads = lldbutil.get_threads_stopped_at_breakpoint( |
| 42 | + process, breakpoint) |
| 43 | + |
| 44 | + self.assertEquals(1, len(threads)) |
| 45 | + self.thread = threads[0] |
| 46 | + self.frame = self.thread.frames[0] |
| 47 | + self.assertTrue(self.frame, "Frame 0 is valid.") |
| 48 | + |
| 49 | + patterns = [ |
| 50 | + # Ensure we report a self with an address. |
| 51 | + r"self\s*=\s*0x[0-9a-fA-F]+", |
| 52 | + # Ensure we think it is an NSObject. |
| 53 | + r"ObjectiveC.NSObject"] |
| 54 | + substrs = [ |
| 55 | + "(%s.%s)" % (module_name, module_name) |
| 56 | + ] |
| 57 | + self.expect("frame variable self", patterns=patterns, |
| 58 | + substrs=substrs) |
| 59 | + |
| 60 | + @decorators.skipUnlessDarwin |
| 61 | + def test_variables_print_from_both_swift_modules(self): |
| 62 | + """Test that variables from two modules can be accessed.""" |
| 63 | + self.build() |
| 64 | + |
| 65 | + # I could not find a reasonable way to say "skipUnless(archs=[])". |
| 66 | + # That would probably be worth adding. |
| 67 | + if self.getArchitecture() != 'x86_64': |
| 68 | + self.skipTest("This test requires x86_64 as the architecture " |
| 69 | + "for the inferior") |
| 70 | + |
| 71 | + exe_name = "main" |
| 72 | + src_a = lldb.SBFileSpec("A.swift") |
| 73 | + line_a = 5 |
| 74 | + src_b = lldb.SBFileSpec("B.swift") |
| 75 | + line_b = 5 |
| 76 | + exe = os.path.join(os.getcwd(), exe_name) |
| 77 | + |
| 78 | + # Create the target |
| 79 | + target = self.dbg.CreateTarget(exe) |
| 80 | + self.assertTrue(target, lldbtest.VALID_TARGET) |
| 81 | + |
| 82 | + # Set the breakpoints |
| 83 | + # breakpoint_a = target.BreakpointCreateBySourceRegex( |
| 84 | + # 'Set breakpoint here', src_a) |
| 85 | + breakpoint_a = target.BreakpointCreateByLocation( |
| 86 | + src_a, line_a) |
| 87 | + self.assertTrue(breakpoint_a.GetNumLocations() > 0, |
| 88 | + lldbtest.VALID_BREAKPOINT) |
| 89 | + |
| 90 | + # breakpoint_b = target.BreakpointCreateBySourceRegex( |
| 91 | + # 'Set breakpoint here', src_b) |
| 92 | + breakpoint_b = target.BreakpointCreateByLocation( |
| 93 | + src_b, line_b) |
| 94 | + self.assertTrue(breakpoint_b.GetNumLocations() > 0, |
| 95 | + lldbtest.VALID_BREAKPOINT) |
| 96 | + |
| 97 | + # Launch the process, and do not stop at the entry point. |
| 98 | + envp = ['DYLD_FRAMEWORK_PATH=.'] |
| 99 | + process = target.LaunchSimple(None, envp, os.getcwd()) |
| 100 | + |
| 101 | + self.assertTrue(process, lldbtest.PROCESS_IS_VALID) |
| 102 | + |
| 103 | + # We should be at breakpoint in module A. |
| 104 | + self.expect_self_var_available_at_breakpoint( |
| 105 | + process, breakpoint_a, "A") |
| 106 | + |
| 107 | + # Jump to the next breakpoint |
| 108 | + process.Continue() |
| 109 | + |
| 110 | + # We should be at breakpoint in module B. |
| 111 | + self.expect_self_var_available_at_breakpoint( |
| 112 | + process, breakpoint_b, "B") |
| 113 | + |
| 114 | + return |
0 commit comments