On Monday, 24 August 2015 23:07:20 David Naylor wrote: > On Saturday, 22 August 2015 21:25:44 Matti Picus wrote: > > I would like to add the freebsd-9-x86-64 binary tgz to our released > > downloads. We still have a number of failing tests showing up on > > http://buildbot.pypy.org/summary?category=freebsd64 > > among them many > > DLOpenError: "opening 'libm.so' with ctypes.CDLL() works, but not with > > c_dlopen()??" > > and the more worrying SIGSEGV in > > http://buildbot.pypy.org/summary/longrepr?testname=unmodified&builder=pypy > > -c -jit-freebsd-9-x86-64&builde5&mod=lib-python.2.7.test.test_io > > > > Could someone proficient in freebsd suggest what is going on? > > Hi Matti, > > I am able to reproduce this on FreeBSD 10.2: > # cat > test.py << __EOF > from ctypes import * > > libc = CDLL("libc.so.7") > dlopen = libc["dlopen"] > > # see <dlfnc.h>: void *dlopen(const char *, int); > dlopen.argtypes = [c_char_p, c_int] > dlopen.restype = c_void_p > > print dlopen(c_char_p("libm.so"), c_int(0)) > __EOF > # python test.py > None
I have found the root cause of this problem (from the FreeBSD-Python team): """ Because dlopen symbol is magic. It is provided by the shared libc.so to satisfy the static linker, but real definition comes from the dynamic linker. The libc.so dlopen() is a null stub. You are asking for the dlopen symbol from libc, which is returned to you in faith, and which cannot load a library for real. While in the C example, you use normal symbol resolution and get the dlopen from the loader. To get a handle to real dlopen with dlopen/dlsym, you should do in C: dlopenX = dlsym(RTLD_DEFAULT, "dlopen"); """ - Konstantin Belousov Please find attached for a patch that fixes this issue. Would you like me to submit a bug report for this patch? I have not translation tested this patch as yet. Regards
--- rpython/rtyper/lltypesystem/ll2ctypes.py.orig 2015-05-31 07:19:51 UTC +++ rpython/rtyper/lltypesystem/ll2ctypes.py @@ -47,6 +47,7 @@ rlock = RLock() _POSIX = os.name == "posix" _MS_WINDOWS = os.name == "nt" _64BIT = "64bit" in host_platform.architecture()[0] +_FREEBSD = sys.platform.startswith('freebsd') # ____________________________________________________________ @@ -1080,8 +1081,11 @@ if ctypes: return ctypes.util.find_library('c') libc_name = get_libc_name() # Make sure the name is determined during import, not at runtime + if _FREEBSD: + RTLD_DEFAULT = -2 # see <dlfcn.h> + rtld_default_lib = ctypes.CDLL("RTLD_DEFAULT", handle=RTLD_DEFAULT, **load_library_kwargs) # XXX is this always correct??? - standard_c_lib = ctypes.CDLL(get_libc_name(), **load_library_kwargs) + standard_c_lib = ctypes.CDLL(libc_name, **load_library_kwargs) # ____________________________________________ @@ -1173,7 +1177,10 @@ def get_ctypes_callable(funcptr, calling not_found.append(libname) if cfunc is None: - cfunc = get_on_lib(standard_c_lib, funcname) + if _FREEBSD and funcname in ('dlopen', 'fdlopen', 'dlsym', 'dlfunc', 'dlerror', 'dlclose'): + cfunc = get_on_lib(rtld_default_lib, funcname) + else: + cfunc = get_on_lib(standard_c_lib, funcname) # XXX magic: on Windows try to load the function from 'kernel32' too if cfunc is None and hasattr(ctypes, 'windll'): cfunc = get_on_lib(ctypes.windll.kernel32, funcname) @@ -1497,13 +1504,12 @@ else: def _where_is_errno(): return standard_c_lib._errno() - elif sys.platform.startswith('linux') or sys.platform == 'freebsd6': + elif sys.platform.startswith('linux'): standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int) def _where_is_errno(): return standard_c_lib.__errno_location() - elif any(plat in sys.platform - for plat in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9')): + elif sys.platform == 'darwin' or sys.platform.startswith('freebsd'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) def _where_is_errno(): return standard_c_lib.__error()
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev