senthamizcoder
senthamizcoder

Reputation: 21

Segmentation Fault when trying to lock a shared memory mutex

Segmentation fault on a shared memory mutex. I have a producer and a consumer processes respectively, the producer inits the shared memory, the shared memory mutex, and writes the data.

The consumer opens the shared memory, tries to lock and read the data.

Without the mutex, the consumer is able to read the data (the data will be inconsistent, but there are no seg faults)

There is a seg fault only when the consumer is trying to lock the mutex.

Changed the flags and the result is the same, checked the return values of the attr and mutex inits, which are all good.

I am a little lost, and I am quite new to working on shared memory.

Any flaws pointed out would be really helpful. Thanks!

Stack:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff79c0c8d in pthread_mutex_lock () from /lib64/libpthread.so.0
(gdb) bt
#0  0x00007ffff79c0c8d in pthread_mutex_lock () from /lib64/libpthread.so.0
#1  0x00000000004008ec in main (argc=1, argv=0x7fffffffde18 "\210\341\377\377\377\177") at cons.c:41
(gdb) p cons_ptr
$1 = (test_str_t *) 0x7ffff7ff7000
(gdb) p cons_ptr->data[0] 
$2 = 873422052  
(gdb) p cons_ptr->magic 
$3 = 43981  
(gdb) p cons_ptr->shm_lock
$4 = {__data = {__lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 128, __spins = 0, __elision = 0, __list = {__prev = 0x0, __next = 0x0}}, 
  __size = '\000' <repeats 16 times>, "\200", '\000' <repeats 22 times>, __align = 0}
(gdb) 


// Header:  

const char *pathname = "test_shm";

typedef struct test_str_{
    uint64_t            magic;
    int                 data[1024];
    pthread_mutex_t     shm_lock;
    uint64_t            magic2;
}test_str_t;

// Producer:  

#include "test_header.h"
#include <time.h>

test_str_t *ptr;

void init_mutex(pthread_mutex_t *mutex){
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(mutex, &attr);
    pthread_mutexattr_destroy(&attr);
}

int main(int argc, char *argv[]) {
    int fd, i = 0, num_int = 1024, rc = 0;
    int size = num_int * sizeof(int);
    fd = shm_open(pathname, O_CREAT|O_RDWR, 0666);
    if(fd == -1) {
        printf("\n shm_open failed \n");
        exit(0);
    }
    rc = ftruncate(fd, sizeof(test_str_t));
    ptr = (test_str_t *)mmap(NULL, sizeof(test_str_t),
                    PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
    if(ptr == MAP_FAILED) {
        printf("\n mmap failed \n");
        exit(0);
    }
    rc = init_mutex(&(ptr->shm_lock));
    if(rc != 0) {
        printf("Mutex Init failed: rc:[%d]\n", rc);
        exit(0);
    }
    ptr->magic = 0xABCD;
    ptr->magic2 = 0xEF12;
    srand(time(0));
    for(i = 0; i < 5; i++) {
        pthread_mutex_lock(&(ptr->shm_lock));
        ptr->data[i] = i;
        pthread_mutex_unlock(&(ptr->shm_lock));
    }
    return 0;
}

// Consumer:  

#include "test_header.h"
#include <time.h>

test_str_t *cons_ptr;

int main(int argc, char *argv[]) {
    int fd, i = 0, num_int = 1024, rc = 0;
    int try_lock = 0;
    int size = num_int * sizeof(int);
    fd = shm_open(pathname, O_RDONLY, 0666);
    if(fd == -1) {
        printf("\n shm_open failed \n");
        exit(0);
    }
    cons_ptr = (test_str_t *)mmap(NULL, sizeof(test_str_t),
                    PROT_READ, MAP_SHARED, fd, 0);
    if(cons_ptr == MAP_FAILED) {
        printf("\n mmap failed \n");
        exit(0);
    }
    if(cons_ptr == NULL) {
        printf("\n NULL Ptr\n");
        return 0;
    }
    printf("Magic: [0x%x] [0x%x]\n", cons_ptr->magic, cons_ptr->magic2);
    //int try_lock = pthread_mutex_lock(&(cons_ptr->shm_lock)); // SEG FAULT
    for(i = 0; i < 5; i++) {
        printf("\nNumber:[%d]\n", cons_ptr->data[i]);
        sleep(1);
    }
    //pthread_mutex_unlock(&(cons_ptr->shm_lock)); // SEG FAULT
    return 0;
}

Upvotes: 1

Views: 1558

Answers (1)

Bob Shaffer
Bob Shaffer

Reputation: 655

(1) one problem is here: ptr->data = rand(); data is an int*, and you have replaced that pointer with a random address. You do this in a couple of places and I'm not seeing exactly what is going on, but it's the most obvious mistake I see right now.

(2) The next thing I see is that in the consumer you open the file read only and map the memory as read only, but pthread_mutex_lock and pthread_mutex_unlock would need to be able to modify the mutex, so that would probably cause some trouble.

Upvotes: 4

Related Questions