]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Work around llvm-symbolizer LD_LIBRARY_PATH issue
authorGreg Hudson <ghudson@mit.edu>
Mon, 23 Dec 2024 22:16:00 +0000 (17:16 -0500)
committerGreg Hudson <ghudson@mit.edu>
Wed, 8 Jan 2025 22:31:39 +0000 (17:31 -0500)
On some platforms llvm-symbolizer is linked against libcurl, which
depends on the krb5 libraries.  When the test suite runs programs with
LD_LIBRARY_PATH pointed at asan-compiled krb5 libraries,
llvm-symbolizer will encounter a dynamic linker error at startup,
interfering with the display of stack traces.

In k5test.py, when the build enables asan, wrap the platform's
symbolizer in a script that unsets LD_LIBRARY_PATH (or similar) and
then runs the real llvm-symbolizer.

.github/workflows/build.yml
src/Makefile.in
src/util/k5test.py

index 2d166f5df094be0c4541585bd5d353080bfa3c0a..8d7d02e74d864d9b51f3916e7eb630fb81a12364 100644 (file)
@@ -13,13 +13,8 @@ jobs:
             matrix:
                 name: [linux-clang, linux-clang-openssl, linux-gcc]
                 include:
-                    # llvm-symbolizer fails on Ubuntu 24.04 until we
-                    # can avoid using LD_LIBRARY_PATH in the test
-                    # suite.  This causes test suite failures due to
-                    # SIGPIPE exits from test programs.  See
-                    # https://github.com/llvm/llvm-project/issues/120915
                     - name: linux-clang
-                      os: ubuntu-22.04
+                      os: ubuntu-latest
                       compiler: clang
                       makevars: CPPFLAGS=-Werror
                       configureopts: --enable-asan
index 352fb9888730fdbd2046f4b58401f0d64c1da93d..e2286c5eedd74eb31bc78df50c32d7a294def7f4 100644 (file)
@@ -515,11 +515,13 @@ testrealm: runenv.py
 
 # environment variable settings to propagate to Python-based tests
 
+ASAN = @ASAN@
 pyrunenv.vals: Makefile
        $(RUN_SETUP); \
        for i in $(RUN_VARS); do \
                eval echo 'env['\\\'$$i\\\''] = '\\\'\$$$$i\\\'; \
        done > $@
+       echo "asan = '$(ASAN)'" >> $@
        echo "tls_impl = '$(TLS_IMPL)'" >> $@
        echo "have_sasl = '$(HAVE_SASL)'" >> $@
        echo "have_spake_openssl = '$(HAVE_SPAKE_OPENSSL)'" >> $@
index f3e0045c2e7486c478d2f4763fa1dea6e9a6bd78..d22cb5c804ad0cb9b9920c8f51fe4d3da5eab423 100644 (file)
@@ -392,6 +392,7 @@ command-line flags.  These are documented in the --help output.
 
 import atexit
 import fcntl
+import glob
 import optparse
 import os
 import shlex
@@ -564,6 +565,31 @@ def _find_srctop():
     return os.path.abspath(root)
 
 
+# Look for the system LLVM symbolizer, matching the logic the asan
+# runtime would use as closely as possible.
+def _find_symbolizer():
+    if sys.platform == 'darwin':
+        f = which('atos')
+        if f is not None:
+            return f
+
+    f = which('llvm-symbolizer')
+    if f is not None:
+        return f
+
+    # Debian-derived systems have versioned symbolizer names.  If any
+    # exist, pick one of them.
+    l = glob.glob('/usr/bin/llvm-symbolizer-*')
+    if l:
+        return l[0]
+
+    f = which('addr2line')
+    if f is not None:
+        return f
+
+    return None
+
+
 # Parse command line arguments, setting global option variables.  Also
 # sets the global variable args to the positional arguments, which may
 # be used by the test script.
@@ -952,6 +978,7 @@ class K5Realm(object):
         if get_creds and create_kdb and create_user and start_kdc:
             self.kinit(self.user_princ, password('user'))
             self.klist(self.user_princ)
+        self._setup_symbolizer()
 
     def _create_empty_dir(self):
         dir = self.testdir
@@ -1038,6 +1065,30 @@ class K5Realm(object):
         env['GSS_MECH_CONFIG'] = self.gss_mech_config
         return env
 
+    # The krb5 libraries may be included in the dependency chain of
+    # llvm-symbolizer, which is invoked by asan when displaying stack
+    # traces.  If they are, asan-compiled krb5 libraries in
+    # LD_LIBRARY_PATH (or similar) will cause a dynamic linker error
+    # for the symbolizer at startup.  Work around this problem by
+    # wrapping the symbolizer in a script that unsets the dynamic
+    # linker variables before calling the real symbolizer.
+    def _setup_symbolizer(self):
+        if runenv.asan != 'yes':
+            return
+        if 'ASAN_SYMBOLIZER_PATH' in self.env:
+            return
+        symbolizer_path = _find_symbolizer()
+        if symbolizer_path is None:
+            return
+        wrapper_path = os.path.join(self.testdir, 'llvm-symbolizer')
+        with open(wrapper_path, 'w') as f:
+            f.write('#!/bin/sh\n')
+            for v in runenv.env:
+                f.write('unset %s\n' % v)
+            f.write('exec %s "$@"\n' % symbolizer_path)
+        os.chmod(wrapper_path, 0o755)
+        self.env['ASAN_SYMBOLIZER_PATH'] = wrapper_path
+
     def run(self, args, env=None, **keywords):
         if env is None:
             env = self.env