Skip to content

Commit 38f415d

Browse files
authored
Merge pull request #4033 from boegel/check_linked_shared_libs_ldd_fail
make check_linked_shared_libs more robust by taking into account that 'ldd' may fail
2 parents ba94dec + 4e5117c commit 38f415d

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

easybuild/tools/systemtools.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
pass
5858

5959
from easybuild.base import fancylogger
60-
from easybuild.tools.build_log import EasyBuildError
60+
from easybuild.tools.build_log import EasyBuildError, print_warning
6161
from easybuild.tools.filetools import is_readable, read_file, which
6262
from easybuild.tools.py2vs3 import OrderedDict, string_type
6363
from easybuild.tools.run import run_cmd
@@ -970,7 +970,10 @@ def check_linked_shared_libs(path, required_patterns=None, banned_patterns=None)
970970
# example output for shared libraries:
971971
# /lib64/libc-2.17.so: ELF 64-bit LSB shared object, x86-64, ..., dynamically linked (uses shared libs), ...
972972
if "dynamically linked" in file_cmd_out:
973-
linked_libs_out, _ = run_cmd("ldd %s" % path, simple=False, trace=False)
973+
# determine linked libraries via 'ldd', but take into account that 'ldd' may fail for strange reasons,
974+
# like printing 'not a dynamic executable' when not enough memory is available
975+
# (see also https://bugzilla.redhat.com/show_bug.cgi?id=1817111)
976+
linked_libs_cmd = "ldd %s" % path
974977
else:
975978
return None
976979

@@ -981,12 +984,19 @@ def check_linked_shared_libs(path, required_patterns=None, banned_patterns=None)
981984
# /usr/lib/libz.dylib: Mach-O 64-bit dynamically linked shared library x86_64
982985
bin_lib_regex = re.compile('(Mach-O .* executable)|(dynamically linked)', re.M)
983986
if bin_lib_regex.search(file_cmd_out):
984-
linked_libs_out, _ = run_cmd("otool -L %s" % path, simple=False, trace=False)
987+
linked_libs_cmd = "otool -L %s" % path
985988
else:
986989
return None
987990
else:
988991
raise EasyBuildError("Unknown OS type: %s", os_type)
989992

993+
out, ec = run_cmd(linked_libs_cmd, simple=False, trace=False, log_ok=False, log_all=False)
994+
if ec == 0:
995+
linked_libs_out = out
996+
else:
997+
print_warning("Determining linked libraries for %s via '%s' failed! Output: '%s'", path, linked_libs_cmd, out)
998+
return None
999+
9901000
found_banned_patterns = []
9911001
missing_required_patterns = []
9921002
for regex in required_regexs:

test/framework/systemtools.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,33 @@ def test_check_linked_shared_libs(self):
10371037
error_msg = "Check on linked libs should fail for %s with %s" % (path, pattern_named_args)
10381038
self.assertFalse(check_linked_shared_libs(path, **pattern_named_args), error_msg)
10391039

1040+
if get_os_type() == LINUX:
1041+
# inject fake 'file' command which always reports that the file is "dynamically linked"
1042+
file_cmd = os.path.join(self.test_prefix, 'bin', 'file')
1043+
write_file(file_cmd, "echo '(dynamically linked)'")
1044+
adjust_permissions(file_cmd, stat.S_IXUSR, add=True)
1045+
1046+
os.environ['PATH'] = os.path.join(self.test_prefix, 'bin') + ':' + os.getenv('PATH')
1047+
1048+
test_file = os.path.join(self.test_prefix, 'test.txt')
1049+
write_file(test_file, 'test')
1050+
1051+
warning_regex = re.compile(r"WARNING: Determining linked libraries.* via 'ldd .*/test.txt' failed!", re.M)
1052+
1053+
self.mock_stderr(True)
1054+
self.mock_stdout(True)
1055+
res = check_linked_shared_libs(test_file, banned_patterns=['/lib'])
1056+
stderr = self.get_stderr()
1057+
stdout = self.get_stdout()
1058+
self.mock_stderr(False)
1059+
self.mock_stdout(False)
1060+
1061+
fail_msg = "Pattern '%s' should be found in: %s" % (warning_regex.pattern, stderr)
1062+
self.assertTrue(warning_regex.search(stderr), fail_msg)
1063+
self.assertFalse(stdout)
1064+
1065+
self.assertEqual(res, None)
1066+
10401067
def test_locate_solib(self):
10411068
"""Test locate_solib function (Linux only)."""
10421069
if get_os_type() == LINUX:

0 commit comments

Comments
 (0)