I wrote a super simple wrapper for a pthread_mutex_t meant to be used between two processes:
//basic version just to test using it between two processes
struct MyLock
{
public:
MyLock() {
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
pthread_mutex_init(&lock, &attr);
}
~MyLock() {
pthread_mutex_destroy(&lock);
pthread_mutexattr_destroy(&attr);
}
lock() {
pthread_mutex_lock(&lock);
}
unlock() {
pthread_mutex_unlock(&lock);
}
private:
pthread_mutexattr_t attr;
pthread_mutex_t lock;
};
I am able to see this lock work fine between regular threads in a process but when I run process A which does the following in a shared memory region:
void* mem; //some shared memory from shm_open
MyLock* myLock = new(mem) MyLock;
//loop sleeping random amounts and calling ->lock and ->unlock
Then process B opens the shared memory object (verified by setting it with combinations of characters that it's the same region of memory) and does this:
MyLock* myLock = reinterpret_cast<MyLock*>(mem);
//same loop for locking and unlocking as process A
but process B segfaults when trying to lock with the backtrace leading to pthread_mutex_lock() in libpthread.so.0
What am I doing wrong?
The backtrace I get from process B looks like this:
in pthread_mutex_lock () from /lib64/libpthread.so.0
in MyLock::lock at MyLock.H:50
in Server::setUpSharedMemory at Server.C:59
in Server::Server at Server.C
in main.C:52
The call was the very first call to lock after reinterpret casting the memory into a MyLock*
. If I dump the contents of MyLock in gdb in the crashing process I see:
{
attr = {
__size = "\003\000\000\200",
__align = -2147483645
},
lock = {
__data = {
__lock = 1
__count = 0,
__owner = 6742, //this is the lightweight process id of a thread in process A
__nusers = 1,
__kind = 131,
__spins = 0,
__list = {
__prev = 0x0,
__Next = 0x0
}
},
__size = "\001\000\000\000\000 //etc,
__align = 1
}
}
so it looks alright (looks like this in the other process gdb as well). I am compiling both applications together using no additional optimization flags either.