Here’s a very simple reproduction code:
class Connection : public juce::InterprocessConnection
{
public:
Connection(bool isClient)
{
if (isClient)
{
connectToSocket("127.0.0.1", 1111, 1000);
sendMessage(juce::MemoryBlock("1111", 4));
}
}
void connectionMade() override{}
void connectionLost() override {}
void messageReceived(const juce::MemoryBlock &message)
{
juce::Thread::sleep(50);
sendMessage(message);
}
};
class Server : public juce::InterprocessConnectionServer
{
public:
Server()
{
beginWaitingForSocket(1111);
clientConnection.reset(new Connection(true));
}
juce::InterprocessConnection * createConnectionObject() override
{
return serverConnections.add(new Connection(false));
}
private:
std::unique_ptr<Connection> clientConnection;
juce::OwnedArray<Connection> serverConnections;
};
class TestThread : public juce::Thread
{
public:
TestThread() : Thread("TestThread")
{
startThread();
}
~TestThread()
{
stopThread(-1);
}
void run() override
{
while (!threadShouldExit())
{
Server server;
sleep(1000);
}
}
};
After you create a instance of TestThread
, sooner or later, you’ll get a crash with the following stack trace:
|>|InterprocessConnectionCrashTest.exe!std::_Load_seq_cst_1(volatile unsigned char * _Tgt=0xddddddddddddddee) 行 296|C++|
|---|---|---|
| |InterprocessConnectionCrashTest.exe!std::_Atomic_load_1(volatile unsigned char * _Tgt=0xddddddddddddddee, std::memory_order _Order=memory_order_seq_cst) 行 338|C++|
| |InterprocessConnectionCrashTest.exe!std::atomic_load_explicit(const std::_Atomic_bool * _Atom=0xddddddddddddddee, std::memory_order _Order=memory_order_seq_cst) 行 495|C++|
| |InterprocessConnectionCrashTest.exe!std::atomic_load(const std::_Atomic_bool * _Atom=0xddddddddddddddee) 行 506|C++|
| |InterprocessConnectionCrashTest.exe!std::_Atomic_bool::operator bool() 行 641|C++|
| |InterprocessConnectionCrashTest.exe!juce::StreamingSocket::write(const void * sourceBuffer=0x0000024a77077a00, int numBytesToWrite=12) 行 487|C++|
| |InterprocessConnectionCrashTest.exe!juce::InterprocessConnection::writeData(void * data=0x0000024a77077a00, int dataSize=12) 行 170|C++|
| |InterprocessConnectionCrashTest.exe!juce::InterprocessConnection::sendMessage(const juce::MemoryBlock & message={...}) 行 162|C++|
| |InterprocessConnectionCrashTest.exe!Connection::messageReceived(const juce::MemoryBlock & message={...}) 行 24|C++|
| |InterprocessConnectionCrashTest.exe!juce::DataDeliveryMessage::messageCallback() 行 259|C++|
| |InterprocessConnectionCrashTest.exe!juce::InternalMessageQueue::dispatchMessage(juce::MessageManager::MessageBase * message=0x0000024a77090e10) 行 202|C++|
| |InterprocessConnectionCrashTest.exe!juce::InternalMessageQueue::dispatchMessages() 行 240|C++|
| |InterprocessConnectionCrashTest.exe!juce::InternalMessageQueue::dispatchNextMessage(bool returnIfNoPendingMessages=false) 行 124|C++|
| |InterprocessConnectionCrashTest.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages=false) 行 266|C++|
| |InterprocessConnectionCrashTest.exe!juce::MessageManager::runDispatchLoop() 行 128|C++|
| |InterprocessConnectionCrashTest.exe!juce::JUCEApplicationBase::main() 行 266|C++|
| |InterprocessConnectionCrashTest.exe!WinMain(HINSTANCE__ * __formal=0x00007ff6d9080000, HINSTANCE__ * __formal=0x0000000000000000, char * __formal=0x0000024a73dd42d9, int __formal=10) 行 106|C++|
| |InterprocessConnectionCrashTest.exe!invoke_main() 行 107|C++|
| |InterprocessConnectionCrashTest.exe!__scrt_common_main_seh() 行 288|C++|
| |InterprocessConnectionCrashTest.exe!__scrt_common_main() 行 331|C++|
| |InterprocessConnectionCrashTest.exe!WinMainCRTStartup() 行 17|C++|
| |kernel32.dll!BaseThreadInitThunk()|未知|
| |ntdll.dll!RtlUserThreadStart()|未知|
Then if you comment out the sleep
before sendMessage
in Connection::messageReceived
, there will be another crash after running for a while: the classic Microsoft Visual C++ Runtime Library Debug Error! abort() has been called
error.
Then if you let the program continue to execute, a new crash stack will appear after a while:
|>|InterprocessConnectionCrashTest.exe!juce::InterprocessConnection::deliverDataInt(const juce::MemoryBlock & data={...}) 行 267|C++|
|---|---|---|
| |InterprocessConnectionCrashTest.exe!juce::InterprocessConnection::readNextMessage() 行 319|C++|
| |InterprocessConnectionCrashTest.exe!juce::InterprocessConnection::runThread() 行 371|C++|
| |InterprocessConnectionCrashTest.exe!juce::InterprocessConnection::ConnectionThread::run() 行 29|C++|
| |InterprocessConnectionCrashTest.exe!juce::Thread::threadEntryPoint() 行 96|C++|
| |InterprocessConnectionCrashTest.exe!juce::juce_threadEntryPoint(void * userData=0x0000021a6cd8e6f0) 行 119|C++|
| |InterprocessConnectionCrashTest.exe!juce::threadEntryProc(void * userData=0x0000021a6cd8e6f0) 行 62|C++|
| |ucrtbased.dll!invoke_thread_procedure(unsigned int(*)(void *) procedure=0x00007ff64efa6f60, void * const context=0x0000021a6cd8e6f0) 行 92|C++|
| |ucrtbased.dll!thread_start<unsigned int (__cdecl*)(void * __ptr64)>(void * const parameter=0x0000021a6cda9590) 行 115|C++|
| |kernel32.dll!BaseThreadInitThunk()|未知|
| |ntdll.dll!RtlUserThreadStart()|未知|
By the way, I use Windows and use Visual Studio 2017 to compile and run this code under the Debug x64 configuration.
Hope the above information can help you solve this bug, thank you.