[Lldb-commits] [PATCH] D81696: [lldb/Test] Fix ASan/TSan workaround for Xcode Python 3

Jonas Devlieghere via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Thu Jun 11 16:33:31 PDT 2020


JDevlieghere created this revision.
JDevlieghere added reviewers: vsk, aprantl.
JDevlieghere updated this revision to Diff 270256.
JDevlieghere added a comment.
JDevlieghere updated this revision to Diff 270258.

Avoid a race that would result in another test finding the copied python before it has been tested.


JDevlieghere added a comment.

Fix typo


The Python 3 interpreter in Xcode has a relative RPATH and dyld fails to load it when we copy it into the build directory. Provide a workaround for the workaround...

  dyld: Library not loaded: @executable_path/../../../../Python3
    Referenced from: /Users/jonas/llvm/build-tsan/lldb-test-build.noindex/copied-python
    Reason: image not found


https://reviews.llvm.org/D81696

Files:
  lldb/test/API/lldbtest.py


Index: lldb/test/API/lldbtest.py
===================================================================
--- lldb/test/API/lldbtest.py
+++ lldb/test/API/lldbtest.py
@@ -29,6 +29,50 @@
     if not os.path.isdir(path):
         raise OSError(errno.ENOTDIR, "%s is not a directory"%path)
 
+# On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim python
+# binary as the ASan interceptors get loaded too late. Also, when SIP is
+# enabled, we can't inject libraries into system binaries at all, so we need a
+# copy of the "real" python to work with.
+def get_darwin_python_interpreter(builddir, executable):
+    # Avoid doing any work if we already copied the binary. This serves as
+    # synchronization between multiple API tests.
+    copied_python = os.path.join(builddir, 'copied-python')
+    if os.path.isfile(copied_python):
+        return copied_python
+
+    # Find the "real" python binary.
+    import shutil, subprocess
+    real_python = subprocess.check_output([
+        executable,
+        os.path.join(os.path.dirname(os.path.realpath(__file__)),
+                     'get_darwin_real_python.py')
+    ]).decode('utf-8').strip()
+
+    # Copy over the real python to a temporary location. We can't put it in the
+    # right place yet, because that might race with other tests running
+    # concurrently.
+    temp_python = os.path.join(builddir, 'temp-python')
+    shutil.copy(real_python, temp_python)
+
+    # Now make sure the copied Python works. The Python in Xcode has a relative
+    # RPATH and cannot be copied.
+    try:
+        # We don't care about the output, just make sure it runs.
+        subprocess.check_output([temp_python, '-V'],
+                                stderr=subprocess.STDOUT)
+    except subprocess.CalledProcessError:
+        # The copied Python didn't work. Assume we're dealing with the Python
+        # interpreter in Xcode. Given that this is not a system binary SIP
+        # won't prevent us form injecting the interceptors so we get away
+        # without using the copy.
+        return real_python
+
+    # The copied Python works. Time to put it in place and start using it from
+    # now on.
+    shutil.copy(temp_python, copied_python)
+    return copied_python
+
+
 class LLDBTest(TestFormat):
     def __init__(self, dotest_cmd):
         self.dotest_cmd = dotest_cmd
@@ -75,25 +119,9 @@
 
         builddir = getBuildDir(cmd)
         mkdir_p(builddir)
-
-        # On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim
-        # python binary as the ASan interceptors get loaded too late. Also,
-        # when SIP is enabled, we can't inject libraries into system binaries
-        # at all, so we need a copy of the "real" python to work with.
-        #
-        # Find the "real" python binary, copy it, and invoke it.
         if 'DYLD_INSERT_LIBRARIES' in test.config.environment and \
                 platform.system() == 'Darwin':
-            copied_python = os.path.join(builddir, 'copied-system-python')
-            if not os.path.isfile(copied_python):
-                import shutil, subprocess
-                python = subprocess.check_output([
-                    executable,
-                    os.path.join(os.path.dirname(os.path.realpath(__file__)),
-                        'get_darwin_real_python.py')
-                ]).decode('utf-8').strip()
-                shutil.copy(python, copied_python)
-            cmd[0] = copied_python
+            cmd[0] = get_darwin_python_interpreter(builddir, executable)
 
         if 'lldb-repro-capture' in test.config.available_features or \
            'lldb-repro-replay' in test.config.available_features:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81696.270258.patch
Type: text/x-patch
Size: 3677 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20200611/ece3d044/attachment.bin>


More information about the lldb-commits mailing list