[Stk] jack backend segfault-on-exit bug

Stephen Sinclair sinclair at music.mcgill.ca
Thu Aug 29 05:56:05 PDT 2013


Hi,

I've been debugging a segfault in RtWvOut/RtAudio when the Jack
backend closes.  It doesn't happen every time, but it seems to happen
fairly often if the exiting program has no "sleep(1)" before exiting.
In other words, testing on Linux with STK 4.4.4, the following program
crashes "sometimes" (i.e., about 1/4 of the times I run it):

int main() {
  RtWvOut *dac = new RtWvOut();
  for (int i=0; i<48000; i++)
    dac->tick(0);
  delete dac;
  // sleep(1);  <-- doesn't crash if this is included
  return 0;
}

Therefore it's obviously a concurrency bug.  The problem seems to be
during the shutdown/drain process, and the crash consistently happens
in the call to jack_client_close().

As far as I can tell, ~RtWvOut() sets the status_ to EMPTYING, waits
for the stream to not be running (ie. drained) and then calls
dac_.closeStream().

During the wait, jackStopStream() is called ***in a thread*** which
ends up calling stopStream(), leading to jack_deactivate().

Meanwhile dac_.closeStream() leads to a call to jack_client_close(),
which crashes.

I suspect the issue is that jack_deactivate() and jack_client_close()
are executing at the same time.  Is there a good reason for
jackStopStream() to be called in the background?  I'm not sure whether
the best solution is to:

1) introduce a mutex for jack calls
2) not do this in a thread
3) dedicate a thread to jack "management" calls if they must run asynchronously.

I think (2) is the simplest, prefered solution, if it works.  At first
glance, replacing in RtApiJack::callbackEvent() the following line:

    pthread_create( &threadId, NULL, jackStopStream, info );

with:

    jackStopStream(info);

seems to fix the problem.  However, I'm not sure if the asynchronous
call was put there for a reason, perhaps to avoid potential deadlocks?

Steve



More information about the Stk mailing list