jack2 icon indicating copy to clipboard operation
jack2 copied to clipboard

Segfault with multiple instances for the server

Open dimitry-ishenko opened this issue 6 months ago • 2 comments

Describe the bug

I launch two instances of the JACK server use the API (jackctl_server_create/open/start(), etc.). If I try to stop the server that was created 2nd before the 1st one, I get SIGSEGV. If I close the 1st server and then the 2nd one, everything is fine. 🤯 In other words, if I do:

  1. Create & start server1.
  2. Create & start server2.
  3. Sleep 1 sec.
  4. Stop & destroy server2. <-- SIGSEGV in jackctl_server_stop().
  5. Stop & destroy server1.

But, if I switch the order of how the servers are stopped, everything is fine:

  1. Create & start server1.
  2. Create & start server2.
  3. Sleep 1 sec.
  4. Stop & destroy server1. <-- OK
  5. Stop & destroy server1. <-- OK

Environment

  • JACK Version: jackdmp version 1.9.21 tmpdir /dev/shm protocol 9
  • Operating System: Ubuntu 24.04
  • Installation: sudo apt install jackd libjack-jackd2-dev

Steps To Reproduce

#include <jack/jack.h>
#include <jack/control.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

void set_param(const JSList *params, const char *name, const char *value)
{
    for (const JSList *node = params; node; node = node->next)
    {
        jackctl_parameter_t *param = (jackctl_parameter_t*)node->data;
        if (!strcmp(jackctl_parameter_get_name(param), name))
        {
            jackctl_parameter_value val;
            strcpy(val.str, value);
            jackctl_parameter_set_value(param, &val);
            break;
        }
    }
}

jackctl_server_t *create_server(const char *server_name, const char *driver_name, const char *device)
{
    jackctl_server_t *server = jackctl_server_create(NULL, NULL);
    set_param(jackctl_server_get_parameters(server), "name", server_name);
    
    jackctl_driver_t *driver;
    for (const JSList *node = jackctl_server_get_drivers_list(server); node; node = node->next)
    {
        driver = (jackctl_driver_t*)node->data;
        if (!strcmp(jackctl_driver_get_name(driver), driver_name)) break;
    }

    if (device) set_param(jackctl_driver_get_parameters(driver), "device", device);

    jackctl_server_open(server, driver);
    jackctl_server_start(server);

    return server;
}

void kill_server(jackctl_server_t *server)
{
    jackctl_server_stop(server);
    jackctl_server_close(server);
    jackctl_server_destroy(server);
}

int main()
{
    jackctl_server_t *server1 = create_server("server1", "alsa", "hw:1");
    jackctl_server_t *server2 = create_server("server2", "alsa", "hw:2");
    
    sleep(1);

    kill_server(server2);
    kill_server(server1);
    
    return 0;
}

Compiled with:

g++ -ggdb jack.cpp -o jack -ljack -ljackserver

Expected vs. actual behavior

Expected the server to exit, so it can be closed and destroyed.

dimitry-ishenko avatar Jun 28 '25 23:06 dimitry-ishenko