This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]