Skip to content

Segfault with multiple instances for the server #1005

@dimitry-ishenko

Description

@dimitry-ishenko

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions