Linking jack and jackserver libraries in same Switcher process causes undefined behaviors
Summary
I get intermittent bug where JackClient
sometime uses JackServerAPI::jack_client_open
instead of JackLibAPI::jack_client_open
.
I recompile Switcher, jack quiddity sometime work, sometime doesn't.
How to reproduce ?
As all intermittent compilation/linking/dynamic object loading, this is hard to reproduce. My development environment and the current production build system scenic-core
managed to work since implementation of jackserver
quiddity. However it now fail to work 8 times out of 10 when trying to build Switcher linked to GStreamer uninstalled SDK Cerbero
.
Start a jack server:
jackd -d dummy --capture 2 --playback 2 --rate 48000 --period 1024
Run this pyquid snippet in GDB :
#!/usr/bin/env python3
import pyquid
import time
sw = pyquid.Switcher("test")
jacksrc_quid = sw.create("jacksrc")
jacksrc_quid.set("started", True)
time.sleep(3)
jacksrc_quid.set("started", False)
# gdb --args python3 jacksrc-test.py
(gdb) run
When shared objects are loaded in the wrong order, we get the wront implementation of jack_client_open
, which tries to start a jack server, even if we already have one running on host. I tried passing Jack flag JackNoStartServer
, which correctly stop our Jack client starting a server when we're lucky and get JackLibAPI::jack_client_open
implementation, but fails when linked to JackServerAPI::jack_client_open
.
Thread 1 "python3" received signal SIGSEGV, Segmentation fault.
__strcmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:112
112 ../sysdeps/x86_64/multiarch/strcmp-avx2.S: No such file or directory.
(gdb) bt
#0 __strcmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:112
#1 0x00007f83b3b9263f in jack_find_driver_descriptor (drivers=drivers@entry=0x1c90b00, name=name@entry=0x0)
at ../common/JackDriverLoader.cpp:405
#2 0x00007f83b3b93db7 in Jack::JackServerGlobals::Init () at ../common/JackServerGlobals.cpp:288
#3 0x00007f83b3b9120a in jack_client_open_aux (client_name=0x7f83b3232000 "helloworld123", options=JackNoStartServer,
status=0x199a268, ap=0x7ffe7cf46c80) at ../common/JackServerAPI.cpp:128
#4 0x00007f83b3b9148b in jack_client_open (ext_client_name=ext_client_name@entry=0x7f83b3232000 "helloworld123",
options=options@entry=JackNoStartServer, status=status@entry=0x199a268) at ../common/JackServerAPI.cpp:161
#5 0x00007f83b32135ce in switcher::quiddities::JackClient::JackClient
Expected behavior
I expect jacksrc
and jacksink
quiddities to always work with host's Jack server, and Switcher never trying to start it's internal Jack server.
I would prefer that our Jack client implementation does not try to start a Jack server process when no Jack server is found (Jack client API default behavior).
What is the frequency of occurrence of this behavior ?
This bug is randomly triggered when linking libswitchershmtojack.so and libswitcherjackserver.so. When you have a bad build, you need to delete /usr/local/switcher-3.5/plugins/libswitcherjackserver.so
file because Switcher automatically loads all plugins at startup, polluting process namespace for jack_client_open
method.
Why is this import to me?
This currently block going forward with using custom GStreamer build for Scenic. sat-mtl/tools/scenic/scenic-core!180 (merged)
Other comment
A jackserver
quiddity have been added to Switcher jack plugin a while back. This makes libswitcherjackserver.so load shared object libjackserver.so.
We end up with both libjack.so and libjackserver.so loaded in process memory space. This is simply not possible by design. I'm surprised that we could get this far.
Jack maintainer explained this issue in a couple of upstream issues, and made sure this is not supported. A Jack application cannot link both jack and jackserver objects.
Possible race condition with jack_client_deactivate/close and JackClient::HandleLatencyCallback?
also, are you running jackctl_server_create and jack_client_open from the same process? (this will lead to quite a few issues if true)
Put the jack_client_open into a separate process, and try again.
Don't link client apps against the jackserver. No application out there does this from what I know.
jack_client_open(JackNoStartServer) tries to start the server?
(as mentioned countless times, mixing libjackserver and libjack stuff won't work...)