Segmentation fault (core dump) First reader-writer problem

180 Views Asked by At
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>

int sleepval = 10, read_num = 0;
int readcnt = 0, writecnt = 0;
pthread_mutex_t mutex;
sem_t rw_mutex;

int randomGenerator(int high, int low){
    srand(time(0));
    return((rand() % (high - low + 1)) + 100);
}

void *reader(void *readno){
    pthread_mutex_lock(&mutex);
    read_num++;
    /* Block the writer if this is the first reader */
    if(read_num == 1){
        sem_wait(&rw_mutex);
    }
    pthread_mutex_unlock(&mutex);
    /* Read sleepval value and print */
    printf("Reader %03d reads %d\n", *((int *)readno), sleepval);
    readcnt++;
    sleep(sleepval / 1000);
    pthread_mutex_lock(&mutex);
    read_num--;
    /*Wake up writer if this is the last reader */
    if(read_num == 0){
        sem_post(&rw_mutex);
    }
    pthread_mutex_unlock(&mutex);
    int num = randomGenerator(500, 100);
    sleep(num / 1000);
}

void *writer(void *writeno){
    int num = randomGenerator(1000, 100);
    sleep(num / 1000);
    num = randomGenerator(50, 10);
    sem_wait(&rw_mutex);
    sleepval = num;
    printf("Writer %02d writes &d\n", *((int*)writeno), sleepval);
    writecnt++;
    sleep(sleepval / 1000);
    sem_post(&rw_mutex);
}

int main(int argc, char *argv[]){
    int r = atoi(argv[1]);
    int w = atoi(argv[2]);
    int second = 0;
    int i, id[100];
    if(r < 1 || r > 100 || w < 1 || w > 10){
        fprintf(stderr, "Usage: readwrite [read](1 - 100) [write](1 - 10)\n");
        exit(-1);
    }
    
    pthread_t read[100], write[10];
    pthread_mutex_init(&mutex, NULL);
    sem_init(&rw_mutex, 0 , 1);

    /* Create threads for readers */
    for(i = 0; i < r; i++){
        id[i] = i;
        pthread_create(&read[i], NULL, (void *)reader, (void *)&id[i]);
    }
    /* Create threads for writers */
    for(i = 0; i < w; i++){
        id[i] = i;
        pthread_create(&write[i], NULL, (void *)writer, (void *)&id[i]);
    }

    sleep(30); //wait for 30 seconds

    /* Signal threads to finish */
    for (i = 0; i < r; i++){
        pthread_join(read[i], NULL);
    }
    for (i = 0; i < w; i++){
        pthread_join(write[i], NULL);
    }

    /* Display number of occurred reads and writes */
    printf("\n==============================\n");
    printf("Number of reads  :\t%03d\n", readcnt);
    printf("Number of writes :\t%03d\n", writecnt);

    pthread_mutex_destroy(&mutex);
    sem_destroy(&rw_mutex);

    return 0;
}

This assignment is about solving the first reader-writer problem. I could compile it in linux using gcc -lpthread -lrt. But when I try to run it using the given format readwrtie 100 10 I got the segmentation fault (core dump) and I don't know why. I tried running with valgrind a.out to see the problem and I couldnt understand. Please help me.

Memcheck, a memory error detector

==19787== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.

==19787== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info

==19787== Command: a.out

==19787==

==19787== Invalid read of size 1

==19787== at 0x57E7AC: ____strtol_l_internal (in /lib/libc-2.12.so)

==19787== by 0x57E50F: strtol (in /lib/libc-2.12.so)

==19787== by 0x57AEB0: atoi (in /lib/libc-2.12.so)

==19787== by 0x8048A32: main (in /gaia/class/student/maih/maih-asgmt3/a.out)

==19787== Address 0x0 is not stack'd, malloc'd or (recently) free'd

==19787==

==19787==

==19787== Process terminating with default action of signal 11 (SIGSEGV)

==19787== Access not within mapped region at address 0x0

==19787== at 0x57E7AC: ____strtol_l_internal (in /lib/libc-2.12.so)

==19787== by 0x57E50F: strtol (in /lib/libc-2.12.so)

==19787== by 0x57AEB0: atoi (in /lib/libc-2.12.so)

==19787== by 0x8048A32: main (in /gaia/class/student/maih/maih-asgmt3/a.out)

==19787== If you believe this happened as a result of a stack

==19787== overflow in your program's main thread (unlikely but

==19787== possible), you can try to increase the size of the

==19787== main thread stack using the --main-stacksize= flag.

==19787== The main thread stack size used in this run was 10485760.

==19787==

==19787== HEAP SUMMARY:

==19787== in use at exit: 0 bytes in 0 blocks

==19787== total heap usage: 0 allocs, 0 frees, 0 bytes allocated

==19787==

==19787== All heap blocks were freed -- no leaks are possible

==19787==

==19787== For counts of detected and suppressed errors, rerun with: -v

==19787== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 13 from 8)

Segmentation fault (core dumped)

1

There are 1 best solutions below

0
Erdal Küçük On

In your writer function, change

printf("Writer %02d writes &d\n", *((int*)writeno), sleepval);
---------------------------^

to

printf("Writer %02d writes %d\n", *((int*)writeno), sleepval);
---------------------------^

In your main function, change

pthread_create(&read[i], NULL, (void *)reader, (void *)&id[i]);
pthread_create(&write[i], NULL, (void *)writer, (void *)&id[i]);

to

pthread_create(&read[i], NULL, reader, &id[i]);
pthread_create(&write[i], NULL, writer, &id[i]);

Add a return statement to the reader and writer function. Remove the unused variable second in the main function.

Try again.