Last active
January 19, 2021 17:34
-
-
Save C0nsultant/fd5ad36728209d2888e87220d4731cec to your computer and use it in GitHub Desktop.
JACK2 SEGFAULT with repeated client names
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env zsh | |
brew install --build-from-source ./jack2.rb | |
clang++ ./Reproducer.cpp ./JackClient.cpp -I. -ljack -L/usr/local/Cellar/jack2/1.9.16/lib/ -std=c++14 -O2 -openmp -o Reproducer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# launch "x64 Native Tools Command Prompt for VS 2019" | |
cl /c .\Reproducer.cpp .\JackClient.cpp /I"C:\Program Files\JACK2\include" /EHsc /O2 /openmp /std:c++14 | |
link /OUT:".\Reproducer.exe" "C:\Program Files\JACK2\lib\libjack64.lib" /SUBSYSTEM:CONSOLE /MACHINE:X64 .\Reproducer.obj .\JackClient.obj |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Jack2 < Formula | |
desc "JACK Audio Connection Kit" | |
homepage "http://jackaudio.org" | |
version "1.9.16" | |
revision 0 | |
url "https://github.com/jackaudio/jack2/archive/v1.9.16.zip" | |
sha256 "f3d00e42d184505a340cffd573372ef19663bc91d2551c78427e79cf428c6bb4" | |
head "https://github.com/jackaudio/jack2.git" | |
uses_from_macos "util-linux" | |
depends_on "aften" => :recommended | |
depends_on "berkeley-db" => :recommended | |
depends_on "eigen" => :recommended | |
depends_on "libsamplerate" => :recommended | |
depends_on "libsndfile" => :recommended | |
depends_on "opus" => :recommended | |
depends_on "pkg-config" => :build | |
depends_on "portaudio" => :recommended | |
depends_on "readline" => :recommended | |
def install | |
system "./waf", "configure", "--prefix=#{prefix}" | |
system "./waf", "build" | |
system "./waf", "install" | |
end | |
plist_options :manual => "jackd -R -X coremidi -d coreaudio" | |
def plist | |
<<~EOS | |
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>Label</key> | |
<string>#{plist_name}</string> | |
<key>WorkingDirectory</key> | |
<string>#{opt_prefix}</string> | |
<key>EnvironmentVariables</key> | |
<dict> | |
<key>PATH</key> | |
<string>/usr/bin:/bin:/usr/sbin:/sbin:#{HOMEBREW_PREFIX}/bin</string> | |
</dict> | |
<key>ProgramArguments</key> | |
<array> | |
<string>#{opt_bin}/jackd</string> | |
<string>-R</string> | |
<string>-X</string> | |
<string>coremidi</string> | |
<string>-d</string> | |
<string>coreaudio</string> | |
</array> | |
<key>RunAtLoad</key> | |
<true/> | |
<key>KeepAlive</key> | |
<true/> | |
</dict> | |
</plist> | |
EOS | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <cstdlib> | |
#include <cstring> | |
#include <iostream> | |
#include <vector> | |
#include "JackClient.h" | |
JackClient::JackClient( | |
std::string name, | |
jack_options_t options, | |
std::string serverName | |
) | |
: m_isActive{ false } | |
{ | |
if (name.length() > jack_client_name_size()) | |
{ | |
std::cerr << "JACK client name length (" | |
<< name.length() | |
<< ") exceeds allowed size (" | |
<< jack_client_name_size() | |
<< "). Truncating name accordingly." | |
<< std::endl; | |
name.resize(jack_client_name_size()); | |
} | |
options = static_cast<jack_options_t>(options | JackServerName | JackNoStartServer | JackUseExactName); | |
jack_status_t status; | |
jack_client_t* client = jack_client_open(name.c_str(), options, &status, serverName.c_str()); | |
auto deleter = [](jack_client_t* client) { | |
if (client != nullptr) | |
{ | |
jack_deactivate(client); | |
jack_client_close(client); | |
} | |
}; | |
m_client = decltype(m_client)(client, deleter); | |
if (m_client == nullptr) | |
{ | |
std::cerr << "Could not open JACK client (status " << status << ")."; | |
if (status & JackServerFailed) | |
std::cerr << " Unable to connect to JACK server."; | |
std::cerr << std::endl; | |
} | |
} | |
JackClient::~JackClient() = default; | |
bool | |
JackClient::activate() | |
{ | |
if (m_isActive) | |
return false; | |
int status = jack_activate(m_client.get()); | |
if (status != 0) | |
{ | |
std::cerr << "Failed to activate client (status " << status << ")." << std::endl; | |
return false; | |
} | |
m_isActive = true; | |
return m_isActive; | |
} | |
bool | |
JackClient::deactivate() | |
{ | |
if (!m_isActive) | |
return false; | |
int status = jack_deactivate(m_client.get()); | |
if (status != 0) | |
{ | |
std::cerr << "Failed to deactivate client (status " << status << ")." << std::endl; | |
return false; | |
} | |
m_isActive = false; | |
return true; | |
} | |
jack_port_t* | |
JackClient::registerPort(std::string name, bool isInput) | |
{ | |
if (name.length() > jack_port_name_size()) | |
{ | |
std::cerr << "JACK port name length (" | |
<< name.length() | |
<< ") exceeds allowed size (" | |
<< jack_port_name_size() | |
<< "). Truncating name accordingly." | |
<< std::endl; | |
name.resize(jack_port_name_size()); | |
} | |
std::string fullName = std::string(jack_get_client_name(m_client.get())) + ":" + name; | |
auto exists = [&fullName](jack_port_t* port) -> bool { | |
return 0 == std::strncmp(jack_port_name(port), fullName.c_str(), fullName.length()); | |
}; | |
if (std::any_of(inputPorts.cbegin(), inputPorts.cend(), exists)) | |
{ | |
std::cerr << "Input Port with name '" << name << "' already exists."; | |
return nullptr; | |
} | |
if (std::any_of(outputPorts.cbegin(), outputPorts.cend(), exists)) | |
{ | |
std::cerr << "Output Port with name '" << name << "' already exists."; | |
return nullptr; | |
} | |
unsigned long flags = (isInput == true) ? JackPortIsInput : JackPortIsOutput; | |
flags |= JackPortIsPhysical; | |
jack_port_t* port = jack_port_register( | |
m_client.get(), | |
name.c_str(), | |
JACK_DEFAULT_AUDIO_TYPE, //mono, f32, PCM | |
flags, | |
0 | |
); | |
if (port == nullptr) | |
std::cerr << "Could not register JACK port." << std::endl; | |
if (isInput) | |
inputPorts.push_back(port); | |
else | |
outputPorts.push_back(port); | |
return port; | |
} | |
void | |
JackClient::setProcessCallback(JackProcessCallback processCallback, void* arg) | |
{ | |
if (m_isActive) | |
{ | |
std::cerr << "Can not set JACK process callback on an active Client." << std::endl; | |
} | |
int status = jack_set_process_callback(m_client.get(), processCallback, arg); | |
if (status != 0) | |
{ | |
std::cerr << "Failed to set client process callback (status " << status << ")." << std::endl; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
// JACK-Windows compatability has not seen much love, avoid erroneous redefinitions | |
#include <cstdint> | |
#define _STDINT_H | |
#include <jack/jack.h> | |
#include <functional> | |
#include <memory> | |
#include <string> | |
#include <vector> | |
class JackClient | |
{ | |
public: | |
explicit JackClient(std::string name, | |
jack_options_t options = JackNullOption, | |
std::string serverName = "default"); | |
~JackClient(); | |
bool activate(); | |
bool deactivate(); | |
jack_port_t* registerPort(std::string name, bool isInput); | |
void setProcessCallback(JackProcessCallback processCallback, void* arg); | |
private: | |
std::vector< jack_port_t* > inputPorts, outputPorts; | |
std::shared_ptr< jack_client_t > m_client; | |
bool m_isActive; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/build-jack2.sh b/build-jack2.sh | |
index f595199..8e42302 100755 | |
--- a/build-jack2.sh | |
+++ b/build-jack2.sh | |
@@ -39,7 +39,7 @@ fi | |
# --------------------------------------------------------------------------------------------------------------------- | |
# jack2 | |
-jack2_args="--prefix=${jack2_prefix}" | |
+jack2_args="--prefix=${jack2_prefix} --debug" | |
if [ "${CROSS_COMPILING}" -eq 1 ]; then | |
if [ "${LINUX}" -eq 1 ]; then | |
diff --git a/setup/env.sh b/setup/env.sh | |
index 10bae13..6d0ed65 100644 | |
--- a/setup/env.sh | |
+++ b/setup/env.sh | |
@@ -47,9 +47,9 @@ PAWPAW_TMPDIR="/tmp" | |
## build flags | |
-BUILD_FLAGS="-O2 -pipe -I${PAWPAW_PREFIX}/include" | |
+BUILD_FLAGS="-O0 -g -pipe -I${PAWPAW_PREFIX}/include" | |
BUILD_FLAGS+=" -mtune=generic -msse -msse2 -ffast-math" | |
-BUILD_FLAGS+=" -fPIC -DPIC -DNDEBUG -D_FORTIFY_SOURCE=2" | |
+BUILD_FLAGS+=" -fPIC -DPIC -D_FORTIFY_SOURCE=2" | |
BUILD_FLAGS+=" -fdata-sections -ffunction-sections -fno-common -fstack-protector -fvisibility=hidden" | |
if [ "${MACOS_UNIVERSAL}" -eq 0 ]; then | |
@@ -90,7 +90,7 @@ if [ "${MACOS}" -eq 1 ]; then | |
LINK_FLAGS+=" -mmacosx-version-min=10.8 -stdlib=libc++ -arch x86_64" | |
fi | |
else | |
- LINK_FLAGS+=" -Wl,-O1 -Wl,--as-needed -Wl,--gc-sections -Wl,--no-undefined -Wl,--strip-all" | |
+ LINK_FLAGS+=" -Wl,-O0 -Wl,--as-needed -Wl,--gc-sections -Wl,--no-undefined" | |
if [ "${WIN32}" -eq 1 ]; then | |
LINK_FLAGS+=" -static -Wl,-Bstatic" | |
if [ "${CROSS_COMPILING}" -eq 0 ] && [ -e "/usr/lib/libssp.a" ]; then |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <memory> | |
#include <vector> | |
#include "JackClient.h" | |
int main(int argc, char* argv[]) { | |
int num_clients = 100; | |
auto callback = [](uint32_t nframes, void* arg) -> int { | |
int tmp = 0; | |
for (uint32_t i = 0; i < nframes; ++i) | |
++tmp; | |
return 0; | |
}; | |
int it = 0; | |
while (true){ | |
std::vector< std::shared_ptr< JackClient > > clients(num_clients); | |
#pragma omp parallel for | |
for (int i = 0; i < num_clients; ++i) { | |
clients[i] = std::make_shared< JackClient >("ClientName" + std::to_string(i) + " (suffx)"); | |
clients[i]->registerPort("input_0", false); | |
clients[i]->registerPort("input_1", false); | |
clients[i]->registerPort("output_0", true); | |
clients[i]->registerPort("output_1", true); | |
clients[i]->setProcessCallback(callback, nullptr); | |
} | |
#pragma omp parallel for | |
for (int i = 0; i < num_clients; ++i) { | |
clients[i]->activate(); | |
} | |
#pragma omp parallel for | |
for (int i = 0; i < num_clients; ++i) { | |
clients[i]->deactivate(); | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment