MonstBlu
MonstBlu

Reputation: 91

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

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.

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.

I tried reinstalling gdb to get it working again, but I failed. It still shows the same error message. I later found the problem myself and marked it in the code below. I'm just curious why something like this sometimes happens when I try to debug some string functions? Like strdup, strtok, strtol, etc.. Am I missing something to install? I hope I can solve this problem completely.

#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 != '\0') {
        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;
}

Upvotes: 1

Views: 3371

Answers (2)

David Johnston
David Johnston

Reputation: 1026

I had this error and it turned out to be that the command line argument wan't being passed in by gdb. Look up the rules for passing in arguments from the command line when invoking a program with gdb.

Upvotes: 1

Employed Russian
Employed Russian

Reputation: 213526

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.

The error message means:

  • crash happened inside GLIBC strtol_l_internal() function
  • GDB can't show you the source of that function because libc6-src (or similar) package is not installed.

Now, looking at the source for strtol_l_internal() is not going to be helpful -- the root cause of the problem is that you called it with incorrect parameter.

You should read man strtol and verify that you satisfied its preconditions.

It looks like you called strtol(NULL, NULL, ...), which is not a valid thing to do. You could use (gdb) up command to find out where the wrong call came from, and fix the caller.

Upvotes: 2

Related Questions