issue with pthreads and dlopen() of libsane.so in some environments
While attempting to create native bindings to libsane for the Dart language I ran into an issue where my test program crashes with a SEGFAULT on exit after having called sane_exit()
. A test case can be found in the following repository, with instructions how to run it:
https://github.com/boekhold/dart-sane-segfault/tree/main
The Dart VM team has helped me look into this, see the following issue:
https://github.com/dart-lang/sdk/issues/47879
After running through GDB we discovered that the crash happens in some pthreads code:
(gdb) bt
#0 0x00007ffff0eab160 in ?? ()
#1 0x00007ffff7f8c5a1 in __nptl_deallocate_tsd () at pthread_create.c:301
#2 0x00007ffff7f8d62a in __nptl_deallocate_tsd () at pthread_create.c:256
#3 start_thread (arg=<optimized out>) at pthread_create.c:488
#4 0x00007ffff7d65293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Some further googling came up with more evidence that I'm not the only one who's run into this issue:
- People working on CUPS for the Fedora project reported this issue here: https://bugzilla.redhat.com/show_bug.cgi?id=1065695
- The author of the Pyinsane2 bindings discovered this as well, and just made the Python version of
sane_exit()
a null-op: https://gitlab.gnome.org/World/OpenPaperwork/pyinsane/-/blob/master/pyinsane2/sane/rawapi.py#L546
What my test program and these 2 cases have in common is that we all load libsane.so
via a dlopen()
call. The japi
Java bindings in the sane-project
itself also use dlopen()
, but I can see that the Test.java
program actually never calls sane_exit()
, so these bindings might be affected as well.
I'm not familiar enough with pthreads or SANE to do much further investigation into this. I'm hoping that somebody more familiar with these topics can have a look to see if this is something that could be addressed in a future release of SANE.