2
2
#
3
3
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
4
4
5
+ import ctypes
5
6
import functools
6
7
import sys
7
8
16
17
_WINBASE_LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000
17
18
18
19
else :
19
- import ctypes
20
+ import ctypes . util
20
21
import os
21
22
22
23
_LINUX_CDLL_MODE = os .RTLD_NOW | os .RTLD_GLOBAL
23
24
25
+ _LIBDL_PATH = ctypes .util .find_library ("dl" ) or "libdl.so.2"
26
+ _LIBDL = ctypes .CDLL (_LIBDL_PATH )
27
+ _LIBDL .dladdr .argtypes = [ctypes .c_void_p , ctypes .c_void_p ]
28
+ _LIBDL .dladdr .restype = ctypes .c_int
29
+
30
+ class Dl_info (ctypes .Structure ):
31
+ _fields_ = [
32
+ ("dli_fname" , ctypes .c_char_p ), # path to .so
33
+ ("dli_fbase" , ctypes .c_void_p ),
34
+ ("dli_sname" , ctypes .c_char_p ),
35
+ ("dli_saddr" , ctypes .c_void_p ),
36
+ ]
37
+
38
+
24
39
from .find_nvidia_dynamic_library import _find_nvidia_dynamic_library
25
- from .supported_libs import DIRECT_DEPENDENCIES , SUPPORTED_WINDOWS_DLLS
40
+ from .supported_libs import DIRECT_DEPENDENCIES , EXPECTED_LIB_SYMBOLS , SUPPORTED_WINDOWS_DLLS
26
41
27
42
28
43
@functools .cache
@@ -62,6 +77,21 @@ def _windows_load_with_dll_basename(name: str) -> int:
62
77
return None
63
78
64
79
80
+ def _load_and_report_path_linux (libname , soname : str ) -> (int , str ):
81
+ handle = ctypes .CDLL (soname , _LINUX_CDLL_MODE )
82
+ for symbol_name in EXPECTED_LIB_SYMBOLS [libname ]:
83
+ symbol = getattr (handle , symbol_name , None )
84
+ if symbol is not None :
85
+ break
86
+ else :
87
+ raise RuntimeError (f"No expected symbol for { libname = !r} " )
88
+ addr = ctypes .cast (symbol , ctypes .c_void_p )
89
+ info = Dl_info ()
90
+ if _LIBDL .dladdr (addr , ctypes .byref (info )) == 0 :
91
+ raise OSError (f"dladdr failed for { soname } " )
92
+ return handle , info .dli_fname .decode ()
93
+
94
+
65
95
@functools .cache
66
96
def load_nvidia_dynamic_library (libname : str ) -> int :
67
97
for dep in DIRECT_DEPENDENCIES .get (libname , ()):
@@ -76,11 +106,12 @@ def load_nvidia_dynamic_library(libname: str) -> int:
76
106
return handle
77
107
else :
78
108
try :
79
- handle = ctypes . CDLL ( found .lib_searched_for , _LINUX_CDLL_MODE )
80
- except OSError :
81
- pass
109
+ handle , abs_path = _load_and_report_path_linux ( libname , found .lib_searched_for )
110
+ except OSError as e :
111
+ print ( f"SYSTEM OSError for { libname = !r } : { e !r } " , flush = True )
82
112
else :
83
113
# Use `cdef void* ptr = <void*><uintptr_t>` in cython to convert back to void*
114
+ print (f"SYSTEM ABS_PATH for { libname = !r} : { abs_path } " , flush = True )
84
115
return handle ._handle # C unsigned int
85
116
found .raise_if_abs_path_is_None ()
86
117
@@ -98,4 +129,5 @@ def load_nvidia_dynamic_library(libname: str) -> int:
98
129
except OSError as e :
99
130
raise RuntimeError (f"Failed to dlopen { found .abs_path } : { e } " ) from e
100
131
# Use `cdef void* ptr = <void*><uintptr_t>` in cython to convert back to void*
132
+ print (f"FOUND ABS_PATH for { libname = !r} : { found .abs_path } " , flush = True )
101
133
return handle ._handle # C unsigned int
0 commit comments