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 [email protected] https://mail.python.org/mailman/listinfo/pypy-dev
