KhoaVo
KhoaVo

Reputation: 376

segmentation fault(core dumped) error message

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

pthread_mutex_t mutex_lock;

/* semaphore declarations */
sem_t students_sem; /* ta waits for a student to show up, student notifies ta his/her arrival */
sem_t ta_sem;       /* students waits for ta to help, ta notifies student he/she is ready to help */

/* the number of waiting students */
int waiting_students;

/* ta sleeping status indicator */
int ta_sleep = 1;
/* the maximum time (in seconds) to sleep */
#define MAX_SLEEP_TIME 3 

/* number of potential students */
#define NUM_OF_STUDENTS 4

#define NUM_OF_HELPS 2

/* number of available seats */
#define NUM_OF_SEATS 2

/* Student IDs */
int stud_id[NUM_OF_STUDENTS];

/* TA and student threads */
pthread_t students_thread[NUM_OF_STUDENTS];
pthread_t ta_thread;

/* function prototype */
void* ta_check(void* p);
void* student_check(void* p);

int main (void) 
{
    /* local variable declaration */
    int i;

    /* initialize mutex and semaphore */
    pthread_mutex_init(&mutex_lock, NULL);
    sem_init(&ta_sem, 0, 0);
    sem_init(&students_sem,0,0);

    /* create ta thread */
    pthread_create(&ta_thread, 0, ta_check,0);

    /* create student threads */
    for (i = 0; i < NUM_OF_STUDENTS; i++)
        pthread_create(&students_thread[i], 0, student_check,(void*)&stud_id[i]);

    /* join student threads */
    for (i = 0; i < NUM_OF_STUDENTS; i++)
        pthread_join(students_thread[i], NULL);

    /* cancel ta thread when all student threads terminate */
    pthread_cancel(ta_thread);
    printf("The TA finished helping all students.\n");

    return 0;
}

void* ta_check(void* p)
{
    /* invoke random number generator */
    rand_r(time(NULL));
    while (1)
    {
        pthread_mutex_lock(&mutex_lock);
        ta_sleep = 1;
        pthread_mutex_unlock(&mutex_lock);
        sem_wait(&students_sem);
        // help a student 
        printf("Helping a student for %d seconds, # of waiting students = %d", MAX_SLEEP_TIME, waiting_students);
        sleep(MAX_SLEEP_TIME);
        // check if there are more student to help
        while (waiting_students > 0)
        {
            sem_post(&ta_sem);
            pthread_mutex_lock(&mutex_lock);
            waiting_students--;
            pthread_mutex_unlock(&mutex_lock);
            // help student
            printf("Helping a student for %d seconds, # of waiting students = %d", MAX_SLEEP_TIME, waiting_students);
            sleep(MAX_SLEEP_TIME);
        }
    }
    return NULL;
}

void* student_check(void* p)
{
    /* invoke random number generator */
    rand_r((unsigned*)1);
    int num_help = 0;
    int seat_taken = 0;

    while (num_help <= NUM_OF_HELPS)
    {
        // check if ta is not sleeping 
        if (!ta_sleep)
        {
            if (!seat_taken)
            {
                if (waiting_students < NUM_OF_SEATS)
                {
                    // student take a seat
                    seat_taken = 1;
                    pthread_mutex_lock(&mutex_lock);
                    waiting_students++;
                    pthread_mutex_unlock(&mutex_lock);
                    printf("Stdudent %d takes a seat, # of waiting student = %d", *(int*)p, waiting_students);
                    sem_wait(&ta_sem); 
                    seat_taken = 0;
                    num_help++;
                }
                else
                {
                    printf("\tStudent %d programming for %d seconds\n",*(int*)p,MAX_SLEEP_TIME);
                    sleep(MAX_SLEEP_TIME);
                    printf("\tStudent %d will try later\n",*(int*)p);
                }
            }
        }
        // check if ta is sleeping
        else if (ta_sleep)
        {
            pthread_mutex_lock(&mutex_lock);
            ta_sleep = 0;
            pthread_mutex_unlock(&mutex_lock);
            sem_post(&students_sem);
            sem_wait(&ta_sem);
            num_help++;
        }
    }
    printf("Student %d is receiving help", *(int*)p);
    return NULL;
}

After I finished fixings all errors and warnings messages for this program, I encountered this error message segmentation fault(core dumped) for the first time. It has never appear before I was debugging this program. Can I get some help with finding where this error occurred. Thank you very much for helping.

Upvotes: 3

Views: 1439

Answers (3)

Dan Mills
Dan Mills

Reputation: 589

This is your problem: rand_r((unsigned*)1) (Also rand_r(time(NULL))

Any time you find yourself casting a literal to a pointer (and you are not doing deeply embedded programming) you should be suspicious (And when you are writing drivers you should be paranoid instead).

In this instance, rand_r WRITES to the memory pointed to by the pointer so this needs to be a per thread int, not a literal.

rand_r(time(NULL) will not segfault but also will not work as you expect because you are in effect re seeding the RNG with the current time every time you call the thing (I expect the RNG output to change precisely once a second in this case).

Easiest thing might be to make the students and TAs small structures and have each contain an int rand_state which you can initialise with random values before starting the threads (The initial seeds), then calling rand_r (&student->rand_state) will give you the result you expect. These structures could also contain the pthread for the student or TA.

Regards, Dan.

Upvotes: 0

hexasoft
hexasoft

Reputation: 677

The rand_r function needs a pointer to an unsigned int (not the same usage than rand.

So you should do:

unsigned int myrand = (unsigned int)time(NULL);
rand_r(&myrand);

Upvotes: 4

Jameson
Jameson

Reputation: 6659

When I run it in gdb, I see a complaint about rand_r():

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff77f6700 (LWP 6018)]
rand_r (seed=0x5639d757) at rand_r.c:31
31  rand_r.c: No such file or directory.
(gdb) bt 
#0  rand_r (seed=0x5639d757) at rand_r.c:31
#1  0x0000000000400af7 in ta_check (p=0x0) at foo.c:71
#2  0x00007ffff7bc4182 in start_thread (arg=0x7ffff77f6700) at pthread_create.c:312
#3  0x00007ffff78f147d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Upvotes: 0

Related Questions