beeware / Python-Apple-support

A meta-package for building a version of Python that can be embedded into a macOS, iOS, tvOS or watchOS project.
MIT License
1.1k stars 159 forks source link

EXC_BAD_ACCESS using libFFI library on device #131

Closed freakboy3742 closed 2 years ago

freakboy3742 commented 2 years ago

Any attempt to use the externally packaged libFFI (instead of the statically linked libFFI) raises EXC_BAD_ACCESS on a physical device. The simulator appears to work fine.

To Reproduce Steps to reproduce the behavior:

  1. Generate an empty iOS app stub
  2. Run the app on a physical device
  3. See error

Expected behavior

App should start as normal.

Environment:

Additional context

3.6 and 3.7 builds (which use a statically linked libFFI) appear to work fine.

3.8 builds prior to b7 (which also used a statically linked libFFI) also appear to work fine.

3.8-b7+ and 3.9+ builds all work on the simulator, but not on device.

The same problem does not appear to exist on macOS; macOS uses a native libFFI provided by Apple.

mansourmoufid commented 2 years ago

I can think of one thing at the intersection of Python and libffi that happened around 3.8: Python started using ffi_closure_alloc and ffi_closure_free instead of allocating closures on the heap.

libffi should define ffi_closure_alloc and ffi_closure_free, and it does:

% nm libFFI/libFFI.a | grep ffi_closure
---------------- T _ffi_closure_alloc
---------------- T _ffi_closure_free

But libpython is not using these symbols from libffi, but rather defining them itself:

% find . -name '*.a' | xargs nm -o | grep ffi_closure
./Python/libPython.a:dynamic_annotations.o: no symbols
./Python/libPython.a:importdl.o: no symbols
./Python/libPython.a:pymath.o: no symbols
./Python/libPython.a:callbacks.o:                  U _ffi_closure_alloc
./Python/libPython.a:callbacks.o:                  U _ffi_closure_free
./Python/libPython.a:malloc_closure.o: ---------------- T _ffi_closure_alloc
./Python/libPython.a:malloc_closure.o: ---------------- T _ffi_closure_free

Note the absence of Py_ffi_closure_alloc and Py_ffi_closure_free. That happens when the preprocessor symbol USING_MALLOC_CLOSURE_DOT_C is not being defined as it should be. I think you'll need to define LIBFFI_INCLUDEDIR explicity:

./configure ... LIBFFI_INCLUDEDIR=/path/to/dir/of/ffi.h