Bigby
Bigby

Reputation: 303

Unable to Find Segfault Cause

The program is supposed to create x amount of threads based on the arguments that are passed to it. argv[1] is the amount main is supposed to sleep, argv[2] is the number of propucer threads, and argv[3] is the number of consumer threads. The program compiles fine and the command I have been using to run it is: program 10 1 1.

I've been staring at this code for a while now and I can't seem to find what is causing the segmentation fault. Maybe a second set of eyes will be able to pick it quickly.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include "buffer.h"

void *producer(void *);
void *consumer(void *);

// Semaphores
sem_t empty;
sem_t full;
pthread_mutex_t mutex;

// Buffer
int placed = 0;
buffer_item buffer[BUFFER_SIZE];
int insert_item(buffer_item item){
    /* INSERT ITEM INTO BUFFER */
    int z;
    sem_wait(&empty);

    //mutex lock
    z = pthread_mutex_lock(&mutex);
    if (z != 0){
        return -1;
    }
    buffer[placed] = item;

    //mutex unlock
    z = pthread_mutex_unlock(&mutex);
    if (z != 0){
        return -1;
    }

       sem_post(&full);
    placed++;
    printf("producer produced %d\n", item);
}

int remove_item(buffer_item *item){
    /* REMOVE ITEM FROM BUFFER */
    int m;
    placed--;
    sem_wait(&full);

    //mutex lock
    m = pthread_mutex_lock(&mutex);
    if (m != 0){
        return -1;
    }
       buffer[placed] = -1;

    //mutex unlock
    m = pthread_mutex_unlock(&mutex);
    if (m != 0){
        return -1;
    }

       sem_post(&empty);
    printf("consumer consumed %d\n", rand);
    return 0;
}

// Main

int main(int argc, char *argv[]){
    int sleepNum, pThreadNum, cThreadNum, p;
    sleepNum = atoi(argv[1]);
    pThreadNum = atoi(argv[2]);
    cThreadNum = atoi(argv[3]);


    // Initialize Semaphores & mutex
    sem_init(&empty, 0, BUFFER_SIZE);
    sem_init(&full, 0, 0);
    pthread_mutex_init(&mutex, NULL);

    // Create producer thread
    pthread_t tid[pThreadNum];

    int g=pThreadNum-1;
    while(g >= 0){
        p = pthread_create(&tid[g], NULL, producer, NULL);
        g--;
    }
    printf("created prod thread");
    // Create consumer thread
    pthread_t kid[cThreadNum];
    g = cThreadNum-1;
    while(g >= 0){
        p = pthread_create(&kid[g], NULL, consumer, NULL);
        g--;
    }

    // Sleep for argv[0]
    sleep(sleepNum);

    // Destroy mutex & semaphores
        sem_destroy(&empty);
        sem_destroy(&full);
        p = pthread_mutex_destroy(&mutex);

    // Exit
    exit(0);
}


// Producer
void *producer(void *param){
    buffer_item rand;
    unsigned int *seed;
    int b;
    while(1){
        sleep(2);
        rand = rand_r(seed);
        b = insert_item(rand);
        if (b < 0){
            printf("Error producing item.");
        }
    }
}

// Consumer
void *consumer(void *param){
    buffer_item rand;
    int d;
    while(1){
        sleep(2);
        d = remove_item(&rand);
        if (d < 0){
            printf("Error removing item");
        }
    }
}

Thanks in advance!

Upvotes: 2

Views: 671

Answers (4)

higgs241
higgs241

Reputation: 629

Here's a great article for finding the causes of segfaults.

Link

Link mirrored here, in case it ever goes down.... you never know.

Upvotes: 0

peeyush
peeyush

Reputation: 2921

compile your program with -g, as gcc -g program.c -lpthread then gdb a.out set breakpoint as b main start and then use s for step by step execution and see where it is falling.

As someone already mentioned that your producer function has uninitialized pointer unsigned int *seed;

also this program has lost wake-up problem associated with it, along with normal unlocking problem ( as in function insert item, what if insert_item thread context-switched before doing placed++. )

Upvotes: 0

sashang
sashang

Reputation: 12184

In the producer you are using an uninitialized pointer. Try allocating some memory for it using malloc. I'm not explaining exactly what it is because you tagged this as homework.

Also don't rely on the output from printf statements to tell you where the program got to when using threads. It helps if you flush the output stream explicitly after each printf, then you'll almost get an idea of the right sequence of events.

Upvotes: 1

Ajit George
Ajit George

Reputation: 3319

On Unix, you can get the backtrace from a segmentation fault by dumping core and examing the corefile in gdb.

$ ulimit -c <max core file size in 1k blocks>
$ gdb program core
gdb> bt

should dump the backtrace, and you can see exactly which line segfaulted.

Upvotes: 2

Related Questions