Segmentation fault found but message before that is being optimized out

℡╲_俬逩灬. 提交于 2019-12-14 03:18:24

问题


I wrote the following code in GDB online debugger :

#include <stdio.h>

int main()
{
  printf("jkjkkjkj");

  int p , n;
  FILE *fp;
  printf("jkjkkjkj2");
  fp = fopen("abc.txt","r");

  while ( (n = getc(fp))!= EOF)
  {
    printf( "the chareacter here is %d \n", n);
  }

  n = fclose(fp);
  return 0;
}

While executing the code I am getting a segmentation fault at the line where I am trying to fetch the characters from the file. I know that as the file does not exist the segmentation fault error is coming.

However, what intrigues me is the absence of the messages that I am trying to print on the screen. I tried checking on debugger and once I found:

optimized out written near the line no

However, I tried putting getchar() here and there, the messages got printed on the screen even if the segmentation fault persists.

How to explain this? Why is this happening? Why are the messages printed when I am putting getchar() at different places?

I had tried writing this code on a Solaris server and compiling using GCC. The code got compiled but I did not get any output message even when a file with the name provided in the directory existed.


回答1:


As answered by Yunnosch, you probably forgot to check against failure of fopen(3). A better habit is to always check that, at least by coding:

  fp = fopen("abc.txt","r"); 
  if (fp == NULL) { perror("fopen abc.txt"); exit(EXIT_FAILURE); };

and take the habit of doing at least that everywhere. Using perror(3) (or strerror(3) with errno(3)) is a useful habit to get, since you want some reason related to the failure (given by errno perhaps thru perror).

More generally, always read the documentation of functions that you are using (for standard functions, at least on some reference website, and possibly in the C11 standard n1570), and take care of handling their failure (at the very least, by checking against failure and exiting with a useful message to stderr); for Unix functions, see their man pages (on Linux, start on intro(2) and intro(3); for Solaris, start with intro(2) & intro(3)..). In your Unix terminal, try also man fopen ... For POSIX standard, start here.


what intrigues me is the absence of the messages that I am trying to print on the screen.

That is simple. stdout is buffered (see also setvbuf(3)), and often line-buffered. So a printf which does not end with a \n has its output still inside the buffer, and not yet on the screen. The habit to get is to almost always end your printf(3) control format string with a newline, or else to flush the buffer explicitly using fflush(3).

For a newbie, there are few reasons to avoid ending your printf with an explicit \n. So use instead

printf("jkjkkjkj\n");

Otherwise, call fflush(NULL); quite often in your program. BTW, for these buffering reasons, fflush(NULL) should be done before calls to system(3), fork(2), execve(2) and other important program-wide functions.


optimized out written near the line no

That probably happens in the C standard library itself (e.g. in getc from some libc.so), which is usually not compiled with debug information. In practice, trust your C standard library: you are much more likely to have bugs in your code that in libc.

Your own source code should be compiled with gcc -Wall -Wextra -g (asking the GCC compiler to give all warnings and debug info in DWARF format, usable by the gdb debugger) and you need to improve your code to get no warnings at all before using the gdb debugger.

Be aware of undefined behavior, spend several hours reading about UB, and be scared of UB.




回答2:


Try guarding against NULL in fp and for good measure make sure the debug output gets printed (as in comment by Some Programmer Dude).

#include <stdio.h>

int main(void)
{    
   int p , n;
   FILE *fp;

   printf("jkjkkjkj2\n");
   fp = fopen("abc.txt","r"); 

   if (NULL != fp)
   {
      while ( (n = getc(fp))!= EOF)
      {
           printf( "the chareacter here is %d \n", n);
      }
      n = fclose(fp);
   } else
   { 
       printf("File opening failed somehow!\n");
   }
   return 0;
}

Note the nice touch (by Basile Starynkevitch) to only close what was successfully opened.



来源:https://stackoverflow.com/questions/50188967/segmentation-fault-found-but-message-before-that-is-being-optimized-out

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!