Search code examples
clldbllvm-clang

Getting a SEGFAULT on an unused symbol


I am quite new to C (still) so please be patient if I misunderstood something fundamental

I have a simple program that should read a file as a string, and then split that string into lines - storing the result into n array of strings. When I run the following code however I get a SEGFAULT - using lldb shows that it is occurring on a usage of strlen inside the libsystem_platform.dylib library despite no usages of the function anywhere in my code.

Here is the full FileIOTest.c file:

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

#define ENDL "\n"

void read_file(const char* path, char** destination) {
    FILE *file;
    long size_in_bytes;
    
    file = fopen(path, "r");
    
    if(file == NULL) {
        fputs("Requested file is invalid", stderr);
        exit(-1);
    }
    
    fseek(file, 0L, SEEK_END);
    size_in_bytes = ftell(file);
    
    fseek(file, 0L, SEEK_SET);  
    
    fread(*destination, sizeof(char), size_in_bytes, file);
    fclose(file);
}

int main() {
    char* file = calloc(1024, sizeof(char));
    read_file("run", &file);

    char* destination[2048];

    char* token = strtok(file, ENDL);
    for(int i = 0; token != NULL; i++) {
        destination[i] = token;
        token = strtok(NULL, ENDL);
    }

    for(int i = 0; i < 2048; i++)
        printf("%s", destination[i]);
}

I have verified that the file reading works - so there is definitely something wrong with my string splitting code but I can't see what exactly is wrong

Any help is really appreciated!

macOS Catalina 15.4 with lldb version lldb-1103.0.22.10 compiled with clang version clang-1103.0.32.62


Solution

  • You have to be sure you dont exceed destination size. and -1 for null char.

     fread(*destination, sizeof(char), min(size_in_bytes, destinationSize - 1), file);
    

    destination[i] doesnt end with null char. You cant use it as parameter of printf

    for(int i = 0; i < 2048; i++)
        printf("%s", destination[i]); // can cause SEGFAULT
    

    and another limit check for destination. i < 2048 should be added to for check.

    for(int i = 0; token != NULL && i < 2048; i++) {
        destination[i] = token;
        token = strtok(NULL, ENDL);
    }