Search code examples
cdebuggingterminallldb

C: Segmentation fault 11 only in terminal, not in debugger


I'm making a program which reads a file, reverses it bit by bit and stores the result in a new file without allocating chunks larger than 1kb. When i run it in the terminal, it creates the file but doesn't write in it, instead it crashes and gives segmentation fault 11. When i try to debug it using lldb the entire code runs without any problems. Does my terminal follow different allocation rules than lldb? How can i solve this?

I've ran the code with large and small files but even with a nearly empty txt file it crashes. I am running osx 10.10.5 with lldb-340.4.119

int const CHUNK_SIZE = 1024;
int chunk_index = 0;
int character;
char new_filename[] = "output";

struct Chunk {
  struct Chunk *previous;
  int data[(CHUNK_SIZE-sizeof(struct Chunk*))/sizeof(int)];
};

struct Chunk* memory = (struct Chunk *)malloc(sizeof(struct Chunk));
struct Chunk* temp;

FILE *fp;
fp = fopen(argv[1], "r");

    // read file into memory
character = fgetc(fp);
do {
  memory->data[chunk_index] = character;
  chunk_index++;
  if ( chunk_index*sizeof(int) > CHUNK_SIZE-sizeof(struct Chunk*)){
    chunk_index = 0;
    temp = (struct Chunk *)malloc(sizeof(struct Chunk));
    temp->previous = memory;
    memory = temp;
  }
  character = fgetc(fp);
}
while (character !=EOF);
chunk_index--;
fclose(fp);


    // write to new file
fp = fopen(new_filename, "wb");

do {
  while (chunk_index >=0) {
    printf("%c", memory->data[chunk_index]);
    fprintf(fp, "%c", memory->data[chunk_index]);
    chunk_index--;
  }

  chunk_index = (CHUNK_SIZE-sizeof(struct Chunk*))/sizeof(int);
  temp = memory;
  memory = memory->previous;
  free(temp);
} while(memory!=NULL);

Solution

  • The difference between running in a debugger and without it may be due to the debugger disabling ASLR. This may hide the problem when you're trying to debug it.

    Try undoing this. It seems that in LLDB it should be done with the command

    settings set target.disable-aslr false
    

    which should undo the disabling of ASLR. In GDB it would be

    set disable-randomization off
    

    Don't forget to restart the program under your debugger (without restarting the debugger!) to make this setting take effect. In GDB it's the run command, something similar should be in LLDB.