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