This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: robust pthread_mutex_t in shared memory
- From: Michal Vaško <mvasko at cesnet dot cz>
- To: libc-help at sourceware dot org
- Date: Tue, 16 Apr 2019 10:20:28 +0200
- Subject: Re: robust pthread_mutex_t in shared memory
Hi,
for anyone wondering, I manage to find out what the problem was. It is having a mutex on an address not dividable by 2, at least that is what it seems on my architecture x86. I have attached a simple program that always reproduces the problem for me. If I change HOLE_SIZE to a multiple of 2, it does not crash. Can anyone comment on this, please? Is this a bug?
Regards,
Michal
On Monday, April 15, 2019 12:06 CEST, Michal Vaško <mvasko@cesnet.cz> wrote:
> Hi Florian,
> sorry for not giving details but I do not know which are relevant and which not. Yes, munmap() followed by mmap() resulting in different address but there is no real backing file, the file descriptor passed to mmap() is obtained from shm_open().
>
> Regards,
> Michal
>
> On Monday, April 15, 2019 11:58 CEST, Florian Weimer <fweimer@redhat.com> wrote:
>
> > * Michal Vaško:
> >
> > > I have a use-case of process-shared mutexes in shared memory. The
> > > memory is even remapped at times but never while the lock is held. I
> > > have encountered some strange behavior and while debugging I wrote a
> > > fairly simple program that I would like to ask for help with. I would
> > > also appreciate if someone could tell me (or point me to where it is
> > > documented) what are the restrictions when using mutexes this way such
> > > as whether the memory can be remapped while a lock in it is held
> > > (probably not possible for robust mutexes, what about the default
> > > ones?) or similar ones.
> >
> > What do you mean by “remapped”? munmap followed by another mmap from
> > the backing file, possibly resulting in a different address?
> >
> > Thanks,
> > Florian
>
>
>
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <pthread.h>
#define HOLE_SIZE 5
int
main(void)
{
pthread_mutexattr_t attr;
pthread_mutex_t *m1, *m2;
int fd;
size_t mlen;
char *addr, *ptr;
fd = shm_open("/test", O_RDWR | O_CREAT | O_TRUNC, 00666);
if (fd == -1) {
return 1;
}
mlen = 2 * sizeof(pthread_mutex_t) + HOLE_SIZE;
if (ftruncate(fd, mlen) == -1) {
return 1;
}
addr = mmap(NULL, mlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
return 1;
}
ptr = addr;
/* init first lock */
m1 = (pthread_mutex_t *)ptr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
pthread_mutex_init(m1, &attr);
pthread_mutexattr_destroy(&attr);
ptr += sizeof *m1;
/* skip hole */
ptr += HOLE_SIZE;
/* init second lock */
m2 = (pthread_mutex_t *)ptr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
pthread_mutex_init(m2, &attr);
pthread_mutexattr_destroy(&attr);
ptr += sizeof *m2;
if (ptr - addr != mlen) {
return 1;
}
/* locking */
pthread_mutex_lock(m1);
pthread_mutex_lock(m2);
/* unlocking */
pthread_mutex_unlock(m1);
pthread_mutex_unlock(m2);
/* cleanup */
pthread_mutex_destroy(m1);
pthread_mutex_destroy(m2);
munmap(addr, mlen);
close(fd);
return 0;
}