无法找到Segfault原因

时间:2012-05-08 21:49:13

标签: c segmentation-fault

该程序应该根据传递给它的参数创建x个线程。 argv [1]是应该睡觉的主量,argv [2]是推测线程的数量,而argv [3]是消费者线程的数量。该程序编译正常,我用来运行它的命令是:程序10 1 1

我已经盯着这段代码了一段时间,我似乎无法找到导致分段错误的原因。也许第二组眼睛能够快速选择它。

#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");
        }
    }
}

提前致谢!

4 个答案:

答案 0 :(得分:2)

在Unix上,您可以通过转储核心并在gdb中检查核心文件来从分段错误中获得回溯。

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

应该转储回溯,你可以确切地看到哪一行是segfaulted。

答案 1 :(得分:1)

在制作人中,您使用的是未初始化的指针。尝试使用malloc为它分配一些内存。我并没有准确解释它是什么,因为你把它标记为家庭作业。

也不要依赖printf语句的输出来告诉你程序在使用线程时的位置。如果你在每个printf之后显式刷新输出流,那么你几乎可以了解正确的事件序列。

答案 2 :(得分:0)

使用-g编译您的程序,为gcc -g program.c -lpthread 然后 gdb a.out 将断点设为 b main start 然后使用s逐步执行,看看它在哪里落下。

正如有人提到你的生成器函数有未初始化的指针unsigned int *seed;

此程序还有lost wake-up problem与之关联,以及正常的解锁问题(如在函数插入项中,如果在执行placed++之前insert_item线程上下文切换了怎么办。)

答案 3 :(得分:0)

这是一篇很好的文章,用于查找段错误的原因。

Link

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