test/race_conditions #9
@ -3,6 +3,9 @@
|
||||
// Author: Unai Blazquez <unaibg2000@gmail.com>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QSignalSpy>
|
||||
@ -137,8 +140,28 @@ TEST(RaceConditionTest, ProducerSurvivesConsumerCrash)
|
||||
}
|
||||
ASSERT_GE(spy.count(), 2) << "Phase 1: producer should have delivered values";
|
||||
|
||||
// "Crash" the consumer: stop + destroy.
|
||||
consumer.stop();
|
||||
// Simulate a hard crash: force-close the consumer's server fd from
|
||||
// outside its thread, causing accept() to fail with EBADF. This is
|
||||
// what happens when the kernel reclaims fds on SIGKILL / abort().
|
||||
//
|
||||
// We find the server fd by calling getsockname() on open fds and
|
||||
// matching against our socket path.
|
||||
for (int fd = 3; fd < 1024; ++fd)
|
||||
{
|
||||
struct sockaddr_un addr = {};
|
||||
socklen_t len = sizeof(addr);
|
||||
if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &len) == 0 &&
|
||||
addr.sun_family == AF_UNIX &&
|
||||
std::string(addr.sun_path) == sock)
|
||||
{
|
||||
::close(fd); // Yank the fd — consumer thread crashes out of accept()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor calls stop(), which joins the (now-exited) thread and
|
||||
// cleans up. In a real crash no cleanup runs, but we can't leak
|
||||
// threads in a test process.
|
||||
}
|
||||
|
||||
// Phase 2: producer is still running with no consumer (sends will fail).
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user