krb5 commit: Work around llvm-symbolizer LD_LIBRARY_PATH issue

ghudson at mit.edu ghudson at mit.edu
Wed Jan 8 18:13:44 EST 2025


https://github.com/krb5/krb5/commit/029e5b4f3c27e608780e3501ee5bacc92e46aa77
commit 029e5b4f3c27e608780e3501ee5bacc92e46aa77
Author: Greg Hudson <ghudson at mit.edu>
Date:   Mon Dec 23 17:16:00 2024 -0500

    Work around llvm-symbolizer LD_LIBRARY_PATH issue
    
    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 |  7 +------
 src/Makefile.in             |  2 ++
 src/util/k5test.py          | 51 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 2d166f5df..8d7d02e74 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -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
diff --git a/src/Makefile.in b/src/Makefile.in
index 352fb9888..e2286c5ee 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -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)'" >> $@
diff --git a/src/util/k5test.py b/src/util/k5test.py
index f3e0045c2..d22cb5c80 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -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


More information about the cvs-krb5 mailing list