线程问题。调试seg-fault

时间:2015-10-20 02:36:11

标签: segmentation-fault pthreads

这是一个家庭工作问题。以下代码适用于单个线程,但是当多个线程运行时,我会遇到seg-faults。我一直在尝试使用valgrind和gdb进行调试,但我无法弄明白。

你看到这个帖子中有什么东西会导致问题吗?

static int parse_line(char *line, const char *delim, char *field[])
{
   char *next;
   int cnt = 0;

   next = strtok(line, delim);
   while (next) {
    if (cnt == MAX_NUM_FIELDS - 1)
    break;
    field[cnt] = (char *) malloc(strlen(next) + 1);
    strcpy(field[cnt++], next);
    next = strtok(NULL, delim);
    }
    field[cnt] = (char *) 0;    /* make the field array be    null-terminated */
    int i;
    for (i = 0; i < cnt; i++) {
    free(field[cnt]);
    }
    return cnt;
}

void *process_file(void *ptr)
{
    char *filename = (char *) ptr;
    char *linebuffer = (char *) malloc(sizeof(char) * MAX_LINE_SIZE);
    char **field = (char **) malloc(sizeof(char *) * MAX_NUM_FIELDS);
    char *end_date = (char *) malloc(sizeof(char) * MAX_LINE_SIZE);

    fprintf(stderr, "%s: processing log file %s\n", program_name,
        filename);
    FILE *fin = fopen(filename, "r");
    if (fin == NULL) {
    fprintf(stderr, "Cannot open file %s\n", filename);
    pthread_exit(1);
    }
    char *s = fgets(linebuffer, MAX_LINE_SIZE, fin);
    if (s != NULL) {
    int num = parse_line(linebuffer, " []\"", field);
    update_webstats(num, field);
    printf("Starting date: %s\n", field[3]);
    free_tokens(num, field);

    while (fgets(linebuffer, MAX_LINE_SIZE, fin) != NULL) {
        int num = parse_line(linebuffer, " []\"", field);
        strcpy(end_date, field[3]);
        update_webstats(num, field);
        free_tokens(num, field);
        strcpy(linebuffer, "");
    }
    printf("Ending date: %s\n", end_date);

    }
    free(end_date);
    free(field);
    free(linebuffer);
    fclose(fin);
    pthread_exit(NULL);
}

2 个答案:

答案 0 :(得分:1)

你的问题是strtok()不能同时从几个线程中使用,因为它使用静态内部状态(它不是可重入的)。

POSIX包含名为strtok()的{​​{1}}的可重入变体 - 您应该使用此代码:

strtok_r()

答案 1 :(得分:0)

我发现了问题。此代码调用strtok,这不是线程安全的。应该是strtokk_r

static int parse_line(char *line, const char *delim, char *field[])
 {
   char *next;
   int cnt = 0;

   next = strtok(line, delim);
   while (next) {
    if (cnt == MAX_NUM_FIELDS - 1)
    break;
    field[cnt] = (char *) malloc(strlen(next) + 1);
    strcpy(field[cnt++], next);
    next = strtok(NULL, delim);
    }
    field[cnt] = (char *) 0;    /* make the field array be    null-terminated */
    int i;
    for (i = 0; i < cnt; i++) {
    free(field[cnt]);
    }
    return cnt;
}