为什么 gdb 显示 /stdlib/strtol_l.c: 没有那个文件或目录?我缺少要安装的东西吗?

Why gdb showed /stdlib/strtol_l.c: No such file or directory? Do I missing something to install?

我试着用-g然后运行gdb编译来找到导致段错误的那一行,但是错误信息让我很困惑。

Program received signal SIGSEGV, Segmentation fault.
__GI_____strtol_l_internal (nptr=0x0, endptr=endptr@entry=0x0, base=base@entry=10, group=group@entry=0, loc=0x7ffff7fb04a0 <_nl_global_locale>)
    at ../stdlib/strtol_l.c:292
292     ../stdlib/strtol_l.c: No such file or directory.

我尝试重新安装 gdb 以使其再次运行,但我失败了。它仍然显示相同的错误消息。后来自己发现了问题,并在下面的代码中标记出来。我很好奇为什么当我尝试调试一些字符串函数时有时会发生这样的事情?像 strdupstrtokstrtol 等。我是不是缺少要安装的东西?希望能彻底解决这个问题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

char buff[255];
#define NUM_BUCKETS 32

typedef struct Customer {
    char* email;
    char* name;
    int shoesize;
    char* food;
    struct Customer* next;
} Customer ;

unsigned long hash(char *str) {
    unsigned long hash = 0;
    int c;

    while (*str != '[=12=]') {
        c = *str;
        hash = ((hash << 5) + hash) + (unsigned char)c;
        str++;
    }
    return hash;
}

Customer *add_friend_to_list(char *email, char *name, int shoesize, char *food, Customer *bucket) {
    Customer* customer;

    customer = malloc(sizeof(Customer));
    customer->name = strdup(name);
    customer->food = strdup(food);
    customer->shoesize = shoesize;
    customer->email = strdup(email);
    customer->next = bucket;

    return customer;
}

void add_consumer_to_hashtable(char *name, char *food, char *email, int shoesize, Customer **buckets, size_t num_buckets) {
    size_t which_bucket = hash(name) % num_buckets;
    buckets[which_bucket] = add_friend_to_list(email, name, shoesize, food, buckets[which_bucket]);
}

int main() {
    Customer* buckets[NUM_BUCKETS] = {NULL};
    int ittime = 0;
    FILE *fp = NULL;
    fp = fopen("customers.tsv", "r");
    while (true) {
        fgets(buff, 255, fp);
        if (feof(fp)) {
            break;
        }
        ittime++;
    }
    
    fclose(fp);

    fp = NULL;
    char *email = (char *)malloc(5 * sizeof(char));
    char *name = (char *)malloc(5 * sizeof(char));
    int shoesize;
    char *food = (char *)malloc(5 * sizeof(char));
    const char s[2] = "\t";
 
    fp = fopen("customers.tsv", "r");
    for (int i = 0; i < ittime + 1; i++) {        //This line cause the Segmentation Fault
        fgets(buff, 255, fp);
        char *token;

        token = strtok(buff, s);
        email = token;
        token = strtok(NULL, s);
        name = token;
        token = strtok(NULL, s);
        shoesize = atoi(token);
        token = strtok(NULL, s);
        food = token;
        add_consumer_to_hashtable(name, food, email, shoesize, buckets, NUM_BUCKETS);
    }

    fclose(fp);

    while (true) {
        char *cmd = (char *)malloc(5 * sizeof(char));

        printf("command: ");
        scanf("%s", cmd);
        if (strcmp(cmd, "add") == 0) {
            char *email1 = (char *)malloc(5 * sizeof(char));
            char *name1 = (char *)malloc(5 * sizeof(char));
            int shoesize1;
            char *food1 = (char *)malloc(5 * sizeof(char));

            printf("email address? ");
            scanf("%s", email1);
            printf("name? ");
            scanf(" %[^\n]", name1);
            printf("shoe size? ");
            scanf("%d", &shoesize1);
            printf("favorite food? ");
            scanf("%s", food1);
            add_consumer_to_hashtable(name1, food1, email1, shoesize1, buckets, NUM_BUCKETS);
            free(name1);
            free(food1);
            free(email1);
        } else if (strcmp(cmd, "lookup") == 0) {
            char *Email = (char *)malloc(5 * sizeof(char));
            printf("email address? ");
            scanf("%s", Email);
            bool exist = false;
            for (int i = 0; i < 32; i++) {
                Customer *cus = buckets[i];
                if (buckets[i] == NULL) {
                    continue;
                }
                while ((cus != NULL)) {
                    if (cus->shoesize == EOF) {
                        break;
                    }
                    if (strcmp(cus->email, Email) == 0) {
                        printf("email: %s\n", cus->email);
                        printf("name: %s\n", cus->name);
                        printf("shoesize: %d\n", cus->shoesize);
                        printf("food: %s\n", cus->food);
                        exist = true;
                        break;
                    }
                    if (cus->next != NULL) {
                        cus = cus->next;
                    } else {
                        break;
                    }
                }
            }
            if (exist == false) {
                printf("user not found!\n");
            }
        } else if (strcmp(cmd, "delete") == 0) {
            char *Email = (char *)malloc(5 * sizeof(char));
            printf("email address? ");
            scanf("%s", Email);
            bool exist = false;
            for (int i = 0; i < 32; i++) {
                Customer *cus = buckets[i];
                if (buckets[i] == NULL) {
                    continue;
                }
                while ((cus != NULL)) {
                    if (cus->shoesize == EOF) {
                        break;
                    }
                    if (strcmp(cus->email, Email) == 0) {
                        free(cus->email);
                        free(cus->food);
                        free(cus->name);
                        free(cus);
                        cus->shoesize = EOF;
                        cus = NULL;
                        exist = true;
                        break;
                    }
                    if (cus->next != NULL) {
                        cus = cus->next;
                    } else {
                        break;
                    }
                }
            }
            if (exist == false) {
                printf("user not found!\n");
            }
        } else if (strcmp(cmd, "list") == 0) {
            for (int i = 0; i < 32; i++) {
                Customer *cus = buckets[i];
                if (buckets[i] == NULL) {
                    continue;
                }
                while ((cus != NULL) && ((cus->shoesize) != EOF)) {
                    printf("email: %s\n", cus->email);
                    printf("name: %s\n", cus->name);
                    printf("shoesize: %d\n", cus->shoesize);
                    printf("food: %s\n", cus->food);
                    if (cus->next != NULL) {
                        cus = cus->next;
                        printf("\n");
                    } else {
                        break;
                    }
                }
            }
        } else if (strcmp(cmd, "quit") == 0) {
            break;
        } else if (strcmp(cmd, "save") == 0) {
            fp = fopen("customers.tsv", "w");
            for (int i = 0; i < 32; i++) {
                Customer *cus = buckets[i];
                if (buckets[i] == NULL) {
                    continue;
                }
                while ((cus != NULL) && ((cus->shoesize) != EOF)) {
                    fprintf(fp, "%s\t%s\t%d\t%s", cus->email, cus->name, cus->shoesize, cus->food);
                    if (cus->next != NULL) {
                        cus = cus->next;
                        fprintf(fp, "\n");
                    } else {
                        break;
                    }
                }
            }
            fclose(fp);
        } else {
            printf("unknown command\n");
        }
    }
    for (int i = 0; i < 32; i++) {
        Customer *tmp;
        Customer *cus = buckets[i];
        if (cus == NULL) {
            continue;
        }
        if (cus->next != NULL) {
            tmp = cus;
            cus = cus->next;
        } else {
            break;
        }
        while ((tmp != NULL)) {
            if (tmp->shoesize != EOF) {
                free(tmp->email);
                free(tmp->food);
                free(tmp->name);
                free(tmp);
            }
            cus->shoesize = EOF;
            cus = NULL;
        }
        if (tmp != NULL) {
            free(tmp);
        }
        if (cus != NULL) {
            free(cus);
        }
    }

    return 0;
}

I tried to compile with -g and then run gdb to find the line that caused the segmentation fault, but the error message confused me.

错误信息的意思是:

  • GLIBC strtol_l_internal() 函数内部发生崩溃
  • GDB 无法向您显示该函数的源代码,因为未安装 libc6-src(或类似的)包。

现在,查看 strtol_l_internal() 的源代码不会有帮助 -- 问题的根本原因是您使用不正确的参数调用它。

您应该阅读 man strtol 并验证您是否满足其先决条件。

您似乎调用了 strtol(NULL, NULL, ...),这不是有效的操作。您可以使用 (gdb) up 命令找出 哪里 错误的呼叫来自哪里,并修复呼叫者。