@@ -49,7 +49,20 @@ def glibc_version_string_ctypes():
49
49
# manpage says, "If filename is NULL, then the returned handle is for the
50
50
# main program". This way we can let the linker do the work to figure out
51
51
# which libc our process is actually using.
52
- process_namespace = ctypes .CDLL (None )
52
+ #
53
+ # We must also handle the special case where the executable is not a
54
+ # dynamically linked executable. This can occur when using musl libc,
55
+ # for example. In this situation, dlopen() will error, leading to an
56
+ # OSError. Interestingly, at least in the case of musl, there is no
57
+ # errno set on the OSError. The single string argument used to construct
58
+ # OSError comes from libc itself and is therefore not portable to
59
+ # hard code here. In any case, failure to call dlopen() means we
60
+ # can't proceed, so we bail on our attempt.
61
+ try :
62
+ process_namespace = ctypes .CDLL (None )
63
+ except OSError :
64
+ return None
65
+
53
66
try :
54
67
gnu_get_libc_version = process_namespace .gnu_get_libc_version
55
68
except AttributeError :
@@ -59,7 +72,7 @@ def glibc_version_string_ctypes():
59
72
60
73
# Call gnu_get_libc_version, which returns a string like "2.5"
61
74
gnu_get_libc_version .restype = ctypes .c_char_p
62
- version_str = gnu_get_libc_version ()
75
+ version_str : str = gnu_get_libc_version ()
63
76
# py2 / py3 compatibility:
64
77
if not isinstance (version_str , str ):
65
78
version_str = version_str .decode ("ascii" )
0 commit comments