Invalid read using valgrind

Viewed 48

After a compilation with no warnings and errors for my file reorg.c, I am running the program using Valgrind and I am getting the following output. I am trying to understand why I am getting a segmentation fault but I can't really find something wrong with line 35:

Memcheck, a memory error detector
  ==29338== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
  ==29338== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
  ==29338== Command: ./reorg /opt/lsde/dataset-sf100/
  ==29338==
  ==29338== Invalid read of size 2
  ==29338==    at 0x109398: main (reorg.c:35)
  ==29338==  Address 0x12cb4008 is not stack'd, malloc'd or (recently) free'd
  ==29338==
  ==29338==
  ==29338== Process terminating with default action of signal 11 (SIGSEGV)
  ==29338==  Access not within mapped region at address 0x12CB4008
  ==29338==    at 0x109398: main (reorg.c:35)
  ==29338==  If you believe this happened as a result of a stack
  ==29338==  overflow in your program's main thread (unlikely but
  ==29338==  possible), you can try to increase the size of the
  ==29338==  main thread stack using the --main-stacksize= flag.
  ==29338==  The main thread stack size used in this run was 8388608.
  ==29338==
  ==29338== HEAP SUMMARY:
  ==29338==     in use at exit: 15,280 bytes in 10 blocks
  ==29338==   total heap usage: 10 allocs, 0 frees, 15,280 bytes allocated
  ==29338==
  ==29338== LEAK SUMMARY:
  ==29338==    definitely lost: 5,120 bytes in 5 blocks
  ==29338==    indirectly lost: 0 bytes in 0 blocks
  ==29338==      possibly lost: 0 bytes in 0 blocks
  ==29338==    still reachable: 10,160 bytes in 5 blocks
  ==29338==         suppressed: 0 bytes in 0 blocks
  ==29338== Rerun with --leak-check=full to see details of leaked memory
  ==29338==
  ==29338== For lists of detected and suppressed errors, rerun with: -s
  ==29338== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
  Segmentation fault (core dumped)

This is the code of the reorg.c program.

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/mman.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <unistd.h>


  #include "utils.h"

  Person *person_map;
  unsigned int *knows_map;
  unsigned short *interest_map;
  unsigned long person_num = 0;

  int main(int argc, char *argv[]) {
    unsigned long file_length;
     
    interest_map = (unsigned short *) mmapr(makepath(argv[1], "interest", "bin"), &file_length);
    printf("amin1");
    knows_map    = (unsigned int *)   mmapr(makepath(argv[1], "knows",    "bin"), &file_length);
    printf("amin2");
    person_map   = (Person *)         mmapr(makepath(argv[1], "person",   "bin"), &file_length);
    printf("amin3");
    knows_map    = (unsigned int *)   mmapr(makepath(argv[1], "knows",    "bin"), &file_length);
    printf("knows");
    person_map   = (Person *)         mmapr(makepath(argv[1], "person",   "bin"), &file_length);
    printf("person");   
    person_num   = file_length/sizeof(person_map);
    int counter=0;
    FILE* fp_knows2 = fopen(makepath(argv[1], "knows2", "bin"), (char*) "w");
    FILE* fp_person2 = fopen(makepath(argv[1], "person2", "bin"), (char*) "w");
    long knows2_bytesize;
    int *knows2_map;
    int *person2_map;
    long person2_bytesize;
        for(long i=0; i<person_num; i++) {
            for(long j = 0; j < person_map[i].knows_n; j++) {

                int friend = knows_map[person_map[i].knows_first+j]; // person in my knows-list
                if (person_map[friend].location == person_map[i].location) {
                    counter++;
                    fwrite(&friend, 1,sizeof(int), fp_knows2);
                }
            }
            if(counter > 0){
                fwrite(&person_map[i], 1, sizeof(int), fp_person2);
            }
            counter=0;
        }
        fclose(fp_knows2);
        fclose(fp_person2);
        person2_map = (int*) mmapr(makepath(argv[1], "person2","bin"), &person2_bytesize);
        knows2_map = (int*) mmapr(makepath(argv[1], "knows2","bin"), &knows2_bytesize);

    return 0;
  }

And this is the code of the utils.h program that am including in:

   #define REPORTING_N 1000000
   #define LINEBUFLEN 1024

    typedef unsigned long byteoffset;
    typedef unsigned int  entrycount;


    typedef struct {
    unsigned long  person_id;
    unsigned short birthday;
    unsigned short location;
    unsigned long  knows_first;
    unsigned short knows_n;
    unsigned long  interests_first;
    unsigned short interest_n;
  } Person;

  void parse_csv(char* fname, void (*line_handler)(unsigned char nfields, char** fieldvals)) {
    long nlines = 0;

    FILE* stream = fopen(fname, "r");
    if (stream == NULL) {
        fprintf(stderr, "Can't read file at %s\n", fname);
        exit(-1);
    }
    char line[LINEBUFLEN];
    char* tokens[10];
    unsigned int col, idx;
    tokens[0] = line;

      while (fgets(line, LINEBUFLEN, stream)) {
        col = 0;
        // parse the csv line into array of strings
        for (idx=0; idx<LINEBUFLEN; idx++) { 
            if (line[idx] == '|' || line[idx] == '\n') {
                line[idx] = '\0';
                col++;
                tokens[col] = &line[idx+1];
            } // lookahead to find end of line
            if (line[idx+1] == '\0') {
                break;
            }
        }
        (*line_handler)(col, tokens);
        nlines++;
        if (nlines % REPORTING_N == 0) {
            printf("%s: read %lu lines\n", fname, nlines);
        }
    }
    fclose(stream);
    }


    FILE* open_binout(char* filename) {
    FILE* outfile;
    outfile = fopen(filename, "wb");
    if (outfile == NULL) {
        fprintf(stderr, "Could not open %s for writing\n", filename);
        exit(-1);
      }
       return outfile;
      }

  
    unsigned short birthday_to_short(char* date) {
    unsigned short bdaysht;
    char dmbuf[3];
    dmbuf[2] = '\0';
    dmbuf[0] = *(date + 5);
    dmbuf[1] = *(date + 6);
    bdaysht = atoi(dmbuf) * 100;
    dmbuf[0] = *(date + 8);
    dmbuf[1] = *(date + 9);
    bdaysht += atoi(dmbuf);
    return bdaysht;
    }

    void* mmapr(char* filename, byteoffset *filelen) {
    int fd;
    struct stat sbuf;
    void *mapaddr;

    if ((fd = open(filename, O_RDONLY)) == -1) {
        fprintf(stderr, "failed to open %s\n", filename);
        exit(1);
    }

    if (stat(filename, &sbuf) == -1) {
        fprintf(stderr, "failed to stat %s\n", filename);
        exit(1);
    }
    
    mapaddr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
    if (mapaddr == MAP_FAILED) {
        fprintf(stderr, "failed to mmap %s\n", filename);
        exit(1);
    }
    *filelen = sbuf.st_size;
    return mapaddr;
    }

    char* makepath(char* dir, const char* file, const char* ext) {
    char* out = (char*) malloc(1024), *sep = (char*) "";
        if (strlen(dir) && dir[strlen(dir)-1] != '/') sep = (char*) "/";
    sprintf(out, "%s%s%s.%s", dir, sep, file, ext);
    return out;
    }
0 Answers
Related