PerlFFI / FFI-Platypus

Write Perl bindings to non-Perl libraries with FFI. No XS required.
91 stars 24 forks source link

Segfault in threaded callback, Windows only. #399

Open jbarrett opened 1 month ago

jbarrett commented 1 month ago

I'll start by saying I don't think this is an issue in Platypus, and what I'm trying to achieve is likely firmly in the realms of "I'm surprised that even sometimes works".

While working on MIDI::RtMidi::FFI, I hit a bit of a wall with the library's callback interface on Windows - calling the closure segfaults. RtMidi creates new threads to run its event loop - closures are called from this thread. I went down a couple rabbit holes on this.

I quickly discounted the idea that stack size differences between Windows and Linux were to blame - we're only passing around some pointers, not large allocations.

I'm also fairly certain there isn't a timing issue (or at least, not an intermittent one), as the crash is consistent.

This crash isn't exclusive to Strawberry - MSYS2's Perl also crashes in the same way.

While working on a minimal example, the only thing I could get to consistently exhibit the same behaviour was calling the closure within a new thread:

https://gist.github.com/jbarrett/913a2ae538fd03225ca9e525c4d30f23

The backtrace here is basically the same as when tracing the crash in rtmidi.dll. It doesn't particularly matter what is on xs/closure.c:56 (I tried adding some prints), the call itself fails.

Callback typedef in rtmidi_c.h and RtMidi/FFI.pm - I'm pretty sure this is correct.

(If you want to slap me across the nose with a rolled up newspaper, I'm fuzzix in #native)

plicease commented 1 month ago

Interesting, thank you or the detailed example. Is the Perl you are using on Linux threaded?

jbarrett commented 1 month ago

It is not! I've added full version info to the gist linked above (D'oh - should have included that).

I have also built a -Dusethreads perl on Linux and traced out a very similar looking segfault. The differentiator doesn't appear to be OS, but threaded perl ... pretty sharp, nicely done!