Closed bepzi closed 2 years ago
That usually means that the plugin crashed and the pipe was broken. Can you try testing with "validate-in-process" enabled and see exactly where it crashes?
"validate-in-process" gave two different results:
// modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp
bool ChildProcessMaster::sendMessageToSlave (const MemoryBlock& mb)
{
if (connection != nullptr)
return connection->sendMessage (mb);
jassertfalse; // this can only be used when the connection is active!
return false;
}
Running pluginval with "validate-in-process" in GDB also yielded the SIGPIPE again, same backtrace as before.
Sorry, I should have been a bit clearer, if you're using the UI, there's an option called "Validate in process", try ticking this and running it again. It shouldn't hit that sendMessageToSlave
path at all then. (If it does, could you post the stack trace please?)
If you're using the command line version, you'll need to pass the "--validate-in-process" option.
My bad. I passed --validate-in-process
and the GUI came up, but the option wasn't ticked.
Now I get this in my terminal emulator (the GUI crashed):
Starting test: pluginval / Open plugin (cold)...
JUCE Assertion failure in juce_Thread.cpp:233
!! killing thread by force !!
terminate called without an active exception
I ran it with GDB and after about 20-30 tries it crashed again, the backtrace is:
Starting test: pluginval / Open plugin (cold)...
JUCE Assertion failure in juce_Thread.cpp:233
--Type <RET> for more, q to quit, c to continue without paging--
Thread 1 "pluginval" received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffff76ed6bb in kill () from /usr/lib/libc.so.6
(gdb) bt
#0 0x00007ffff76ed6bb in kill () from /usr/lib/libc.so.6
#1 0x00005555557348c7 in juce::Thread::stopThread (this=this@entry=0x555555f8bff8, timeOutMilliseconds=timeOutMilliseconds@entry=5000) at ../../modules/juce/modules/juce_core/threads/juce_Thread.cpp:233
#2 0x0000555555610f6f in ValidatorSlaveProcess::~ValidatorSlaveProcess (this=0x555555f8bfe0, __in_chrg=<optimized out>) at ../../Source/Validator.cpp:312
#3 ValidatorSlaveProcess::~ValidatorSlaveProcess (this=0x555555f8bfe0, __in_chrg=<optimized out>) at ../../Source/Validator.cpp:313
#4 0x000055555560e54f in std::default_delete<ValidatorSlaveProcess>::operator() (__ptr=<optimized out>, this=0x555555fb0b98) at /usr/include/c++/10.1.0/bits/unique_ptr.h:78
#5 std::unique_ptr<ValidatorSlaveProcess, std::default_delete<ValidatorSlaveProcess> >::~unique_ptr (this=0x555555fb0b98, __in_chrg=<optimized out>) at /usr/include/c++/10.1.0/bits/unique_ptr.h:360
#6 ValidatorMasterProcess::~ValidatorMasterProcess (this=0x555555fb0a50, __in_chrg=<optimized out>) at ../../Source/Validator.cpp:543
#7 0x000055555560e703 in ValidatorMasterProcess::~ValidatorMasterProcess (this=0x555555fb0a50, __in_chrg=<optimized out>) at ../../Source/Validator.cpp:543
#8 0x000055555560b525 in std::default_delete<ValidatorMasterProcess>::operator() (__ptr=<optimized out>, this=0x555555decd58) at /usr/include/c++/10.1.0/bits/unique_ptr.h:78
#9 std::__uniq_ptr_impl<ValidatorMasterProcess, std::default_delete<ValidatorMasterProcess> >::reset (__p=0x0, this=0x555555decd58) at /usr/include/c++/10.1.0/bits/unique_ptr.h:181
#10 std::unique_ptr<ValidatorMasterProcess, std::default_delete<ValidatorMasterProcess> >::reset (__p=0x0, this=0x555555decd58) at /usr/include/c++/10.1.0/bits/unique_ptr.h:455
#11 Validator::handleAsyncUpdate (this=0x555555decd00) at ../../Source/Validator.cpp:773
#12 0x00005555557bb426 in juce::AsyncUpdater::AsyncUpdaterMessage::messageCallback (this=<optimized out>) at ../../modules/juce/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp:34
#13 0x00005555557c2279 in juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const (__closure=0x555555dec968, fd=4)
at ../../modules/juce/modules/juce_core/memory/juce_ReferenceCountedObject.h:392
#14 0x00005555557c2362 in std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) (__f=...) at /usr/include/c++/10.1.0/bits/invoke.h:148
#15 std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__is_invocable&&, (juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&)...) (__fn=...)
at /usr/include/c++/10.1.0/bits/invoke.h:153
#16 std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (__functor=..., __args#0=<optimized out>)
at /usr/include/c++/10.1.0/bits/std_function.h:291
#17 0x00005555557c1147 in std::function<void (int)>::operator()(int) const (this=this@entry=0x555555dec968, __args#0=<optimized out>, __args#0@entry=4) at /usr/include/c++/10.1.0/bits/std_function.h:248
#18 0x00005555557c11f7 in juce::InternalRunLoop::dispatchPendingEvents (this=this@entry=0x555555dec8e0) at ../../modules/juce/modules/juce_events/native/juce_linux_Messaging.cpp:186
#19 0x00005555557ba41a in juce::MessageManager::dispatchNextMessageOnSystemQueue (returnIfNoPendingMessages=returnIfNoPendingMessages@entry=false)
at ../../modules/juce/modules/juce_events/native/juce_linux_Messaging.cpp:294
#20 0x00005555557ba4fe in juce::MessageManager::runDispatchLoop (this=0x555555dec870) at ../../modules/juce/modules/juce_events/messages/juce_MessageManager.cpp:128
#21 0x00005555557bb378 in juce::JUCEApplicationBase::main () at ../../modules/juce/modules/juce_events/messages/juce_ApplicationBase.cpp:262
#22 0x00005555557bb3c6 in juce::JUCEApplicationBase::main (argc=<optimized out>, argv=<optimized out>) at ../../modules/juce/modules/juce_events/messages/juce_ApplicationBase.cpp:240
#23 0x00005555555e8e68 in main (argc=<optimized out>, argv=<optimized out>) at ../../Source/Main.cpp:183
That code is:
bool Thread::stopThread (const int timeOutMilliseconds)
{
// agh! You can't stop the thread that's calling this method! How on earth
// would that work??
jassert (getCurrentThreadId() != getThreadId());
const ScopedLock sl (startStopLock);
if (isThreadRunning())
{
signalThreadShouldExit();
notify();
if (timeOutMilliseconds != 0)
waitForThreadToExit (timeOutMilliseconds);
if (isThreadRunning())
{
// very bad karma if this point is reached, as there are bound to be
// locks and events left in silly states when a thread is killed by force..
jassertfalse; // <----------- CRASHES HERE
Logger::writeToLog ("!! killing thread by force !!");
killThread();
threadHandle = nullptr;
threadId = {};
return false;
}
}
return true;
}
I think you need to print out the stack traces from the other running threads. This is indicating that the main thread is trying to delete a background thread (the ValidatorSlaveProcess
) whilst it is still running. You need to view the stack trace of that thread to see what's blocking it.
I think this should be fixed with 1.0.0 as it doesn't use this pipe mechanism any more
This is from a pluginval build from the
develop
branch.Trying to test a "Hello World" VST2 plugin on Arch Linux. When running pluginval in Debug mode, it will sometimes crash with "SIGPIPE, Broken pipe". This is a Rust project, it's pretty much just the example plugin from the vst-rs README.
EDIT: The fact that it's Rust-based doesn't seem to matter. I was able to recreate this with a standard C++ JUCE-based VST2 plugin.
When running in Release mode, it crashes maybe 9/10 times. When running in debug mode, it crashes maybe 1 in 10 times.