girffi.c: new API for libffi closures
This MR fixes segfaults from freeing the return value of g_callable_info_prepare_closure()
.
On macOS with ARM M1 cpus (with any libffi version AFAICT), and on Linux with libffi >= 3.4, static exec trampolines are used for closures. This makes the assumption in g_callable_info_prepare_closure()
erroneous: the trampoline executable pointer does not have the same pointer as the closure. Attempting to free that executable pointer causes a segfault.
This MR does as discussed in !283 (closed):
- introduce a new API with correct semantics, i.e. return the closure’s address
- I’ve somewhat improvised the naming, please advise
- maintain and deprecate the previous API, with warnings
- stop the previous API from dereferencing invalid pointers (on hosts where it can be an issue only) by leaking the memory
- Leaking seems a reasonable best-effort, please see discussion below and advise
- I’ve put this between v1.72 define guards, as this is the milestone set on !283 (closed)
Leaking the memory seems unavoidable if maintaining the old behaviour in the existing API, as the pointer that needs to be free’d is lost when the function returns.
One way to avoid leaking memory, but would require a lot of extra work, would be to maintain a static map (maybe a GLib HashTable?) inside girffi.c, mapping each GIClosureWrapper->native_address
value to its parent GIClosureWrapper*
pointer. I’m not sure this would make a lot of sense though, it would only target hosts that have static exec trampolines, e.g. that risk segfaulting until they transition to the new API.
Any feedback on how to advance this issue is welcome − I have some time for follow-up in the upcoming days.