On Tuesday, 25 August 2015 23:27:35 David Naylor wrote: > On Wednesday, 26 August 2015 00:09:14 Matti Picus wrote: > > On 25/08/15 21:26, David Naylor wrote: > > > > 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 > > > > I committed your patches as c2f97b8c2415, the last chunk looks strange > > (why > > standard_c_lib.__error.restype ? ) , but let's give it a shot and see what > > happens. Matti > > The last chunk was unrelated to this change - it was just cleaning up > references to FreeBSD. > > Although the tests now pass when run with python they still do not pass when > run from pypy. > > It appears pypy does not properly handle ctypes.CDLL(name, handle=X) where X > is an integer as returned by dlopen(3). I have an idea on how to implement > the fix but that will need to wait for tomorrow.
Please find attached for a patch that adds support for: ctypes.CDLL(name, handle=X) The patch includes tests for the pypy and rpython changes. I am not sure about the policy regarding changes to the python libraries and thus did not add a unit test there (the standard tests are lacking one for handle support anyway). I have translation tested the change and the previous fix I submitted now works on pypy :-D. I also filed an issue #2126 to clean up the handling of 'freebsd' for sys.platform. Lastly, regarding the segfault: it appears to be threading related. I'll file an issue detailing all the stack traces and anything else that I can find that would be helpful. Regards
--- lib-python/2.7/ctypes/__init__.py.orig 2015-05-31 07:19:51 UTC +++ lib-python/2.7/ctypes/__init__.py @@ -367,6 +367,8 @@ class CDLL(object): self._handle = _ffi.CDLL(name, mode) else: self._handle = _ffi.WinDLL(name, mode) + elif isinstance(handle, (int, long)): + self._handle = _ffi.CDLL(name, handle=handle) else: self._handle = handle --- pypy/module/_rawffi/alt/interp_funcptr.py.orig 2015-05-31 07:19:51 UTC +++ pypy/module/_rawffi/alt/interp_funcptr.py @@ -9,7 +9,7 @@ from rpython.rtyper.lltypesystem import from rpython.rlib import jit from rpython.rlib import libffi from rpython.rlib.clibffi import get_libc_name, StackCheckError, LibFFIError -from rpython.rlib.rdynload import DLOpenError +from rpython.rlib.rdynload import DLLHANDLE, DLOpenError from rpython.rlib.rarithmetic import r_uint from rpython.rlib.objectmodel import we_are_translated from pypy.module._rawffi.alt.type_converter import FromAppLevelConverter, ToAppLevelConverter @@ -314,7 +314,7 @@ W_FuncPtr.typedef = TypeDef( # ======================================================================= class W_CDLL(W_Root): - def __init__(self, space, name, mode): + def __init__(self, space, name, mode, handle=rffi.cast(DLLHANDLE, 0)): self.flags = libffi.FUNCFLAG_CDECL self.space = space if name is None: @@ -322,7 +322,7 @@ class W_CDLL(W_Root): else: self.name = name try: - self.cdll = libffi.CDLL(name, mode) + self.cdll = libffi.CDLL(name, mode, handle) except DLOpenError, e: raise wrap_dlopenerror(space, e, self.name) @@ -339,9 +339,9 @@ class W_CDLL(W_Root): "No symbol %s found in library %s", name, self.name) return space.wrap(address_as_uint) -@unwrap_spec(name='str_or_None', mode=int) -def descr_new_cdll(space, w_type, name, mode=-1): - return space.wrap(W_CDLL(space, name, mode)) +@unwrap_spec(name='str_or_None', mode=int, handle=int) +def descr_new_cdll(space, w_type, name, mode=-1, handle=0): + return space.wrap(W_CDLL(space, name, mode, rffi.cast(DLLHANDLE, handle))) W_CDLL.typedef = TypeDef( --- pypy/module/_rawffi/alt/test/test_funcptr.py.orig 2015-05-31 07:19:51 UTC +++ pypy/module/_rawffi/alt/test/test_funcptr.py @@ -643,3 +643,13 @@ class AppTestFFI(BaseAppTestFFI): f_name = libfoo.getfunc('AAA_first_ordinal_function', [], types.sint) f_ordinal = libfoo.getfunc(1, [], types.sint) assert f_name.getaddr() == f_ordinal.getaddr() + + def test_handle(self): + if self.iswin32: + skip("unix specific") + from _rawffi.alt import CDLL, types + RTLD_DEFAULT = -2 # see <dlfcn.h> + libc = CDLL("<None>", handle=RTLD_DEFAULT) + isdigit = libc.getfunc('isdigit', [types.sint], types.sint) + res = isdigit(49) + assert res == 1 --- rpython/rlib/libffi.py.orig 2015-05-31 07:19:51 UTC +++ rpython/rlib/libffi.py @@ -414,14 +414,19 @@ class Func(AbstractFuncPtr): # XXX: it partially duplicate the code in clibffi.py class CDLL(object): - def __init__(self, libname, mode=-1): + def __init__(self, libname, mode=-1, handle=rffi.cast(DLLHANDLE, 0)): """Load the library, or raises DLOpenError.""" - self.lib = rffi.cast(DLLHANDLE, 0) - with rffi.scoped_str2charp(libname) as ll_libname: - self.lib = dlopen(ll_libname, mode) + if handle != rffi.cast(DLLHANDLE, 0): + self.ismanaged = False + self.lib = handle + else: + self.ismanaged = False + self.lib = rffi.cast(DLLHANDLE, 0) + with rffi.scoped_str2charp(libname) as ll_libname: + self.lib = dlopen(ll_libname, mode) def __del__(self): - if self.lib: + if self.lib and self.ismanaged: dlclose(self.lib) self.lib = rffi.cast(DLLHANDLE, 0) --- rpython/rlib/test/test_libffi.py.orig 2015-05-31 07:19:51 UTC +++ rpython/rlib/test/test_libffi.py @@ -625,5 +625,19 @@ class TestLibffiCall(BaseFfiTest): chain = ArgChain() assert 24 == f_by_ordinal.call(chain, lltype.Signed, is_structĂșlse) - - + else: + def test_handle(self): + """ + RPY_EXPORTED + int add_xy(int x, int y) + { + return x + y; + } + """ + from rpython.rlib.rdynload import dlopen, dlclose + handle = dlopen(self.libfoo_name) + libfoo = CDLL("<None>", handle=handle) + func = (libfoo, 'add_xy', [types.sint, types.sint], types.sint) + res = self.call(func, [50, 8], lltype.Signed) + assert res == 58 + dlclose(handle)
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