Skip to main content

Segmentation Fault : behind the code

Segmentation fault
Segmentation fault (core dumped)

Did you just look at your laptop and said, "This is it buddy, don't check my patience, you are going to get hurt !!!".

If you are in this situation, then just try to understand the concept behind segmentation fault and forget the headache ;-)

Segmentation fault is the exception which occurs when a program tries to access an invalid memory. 
In simple words, it means accessing a memory which does not belong to you or you do not have authorization to access it. 

To resolve this, you must know about GNU Debugger(GDB), but if you are SHORT OF TIME then first try following example:

1  #include<stdio.h>
2  int main()
3  {
4   int *p;
5   *p= 7;
6   printf("Output = %d\n",*p);
7  }

 If we run this program, we will get Segmentation fault:

user@gene-laptop:~$ gcc -g segment.c
user@gene-laptop:~$ ./a.out
Segmentation fault (core dumped)

The -g option in gcc is used so that later this program can be debugged using GDB."If you don't know about GDB, just get along and follow the steps :)"

Now, debug your program as

user@gene-laptop:~$ gdb ./a.out
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/user/a.out...done.
(gdb) run
Starting program: /home/user/a.out 

Program received signal SIGSEGV, Segmentation fault.

0x080483f1 in main () at segment.c:5
5 *p=7;
(gdb) 

This means that we are trying to access an invalid memory at line 5. How??
It's because the pointer variable 'p' doesn't point to a memory location and when we are trying to write to this location. Verify it :

(gdb) print p
$1 = 0x0

So, its showing that the value of 'p' is NULL. To solve this, you should assign a memory location to this pointer variable.

1 #include<stdio.h>
2 int main()
3  {
4   int *p;
5   int a=0;
6   p = &a;  // Now the pointer is pointing to a valid memory location
7   *p=7;
8   printf("Output = %d\n",*p);
9  }

user@gene-laptop:~$ gcc -g segment.c
user@gene-laptop:~$ ./a.out
Output = 7

Explore some more examples : 

To understand this concept more deeply, first you should thoroughly understand GDB. Read it from here :
GNU Debugger (GDB) 

After that, look at some more examples below and try to follow the reason of segmentation fault :


example #1 :

1   #include<stdio.h>
2   const int i=5;
3   int main()
4   {
5     int*p;
6     p=&i;
7     *p=8;
8     printf("%d\n",*p);
9   }

 In the above program, we are trying to write to restricted(read-only constant integer) memory location.

example #2 :

1   #include<stdio.h>
2   #include<string.h>
3   int main()
4   {
5     char *str1 = "system";
6     char *str2 = "genes";
7     strcpy(str1,str2);
8     printf("%s %s\n",str1, str2);
9     return 0;
10  }

In this program, str1 is just a pointer(character type) which is not pointing to any valid memory location. So when we try to copy the contents of str2 and attempt to write that to an invalid memory location, Segmentation fault occurs. As a warning, we should not even store a string directly to a pointer variable(line 5 and 6).

user@gene-laptop:~$ gdb ./a.out
.
.
(gdb) run
Starting program: /home/user/a.out 

Program received signal SIGSEGV, Segmentation fault.

0xb7ea4ff2 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) backtrace
#0  0xb7ea4ff2 in ?? () from /lib/i386-linux-gnu/libc.so.6
#1  0x08048441 in main () at segment.c:7
.
.
As our only interest is to find out that where our program crashed i.e in main() function. So we further check out details of frame 1.
.
.
(gdb) frame 1
#1  0x08048441 in main () at segment.c:7
7    strcpy(str1,str2);


example #3:

1  #include<stdio.h>
2  int main()
3  {
4   char ch;
5   FILE *fp;
6   fp=fopen("user.txt", "r");
7   while((ch = getc(fp))!=-1)
8   printf("%c", ch);
9   fclose(fp);
10  return 0;
11 }


Run this program:

user@gene-laptop:~$ gcc -g test.c
user@gene-laptop:~$ ./a.out
Segmentation fault (core dumped)
user@gene-laptop:~$ gdb ./a.out
.
.
.
(gdb) run
Starting program: /home/user/a.out

Program received signal SIGSEGV, Segmentation fault.
0xb7e886de in getc () from /lib/i386-linux-gnu/libc.so.6
(gdb) backtrace
#0  0xb7e886de in getc () from /lib/i386-linux-gnu/libc.so.6
#1  0x080484d2 in main () at test.c:7
(gdb) frame 1
#1  0x080484d2 in main () at test.c:7
7                  while((ch = getc(fp))!=-1)
.
Now ,check the value of file pointer fp and you will find out that 'fp' is NULL.
.
(gdb) print fp
$1 = (FILE *) 0x0
(gdb)

In this scenario, there is no logical error. It's just a case you may encounter. Here, the culprit is fopen() function. If the file "user.txt" is not present in the concerned directory, then getc() function will give segmentation fault as it will not know from where to fetch the data. So, it is advisable to check the return value of fopen() like functions(malloc, calloc etc).

-----------------------------------------------------------------------------------------------------------
If this article helped you, please like it. If you find anything wrong or confusing, please give your suggestions :-)

Comments

Popular posts from this blog

error: invalid application of ‘sizeof’ to incomplete type ‘struct ’

list.c:47:39: error: invalid application of ‘sizeof’ to incomplete type ‘struct Litsnode’ So, I was trying to run a program based on linked list and this is what I got. This is a very silly problem. I am mentioning it here just to help those who got frustrated like me :-\ Let me show you the line where this error occurred : 46   struct Listnode * newnode; 47   newnode = (struct Listnode *) malloc(sizeof(struct Litsnode)); Now, View it properly. Check the name(spelling) of the structure mentioned to sizeof : " struct Li ts node ". Though the defined name of the structure was : " struct Listnode " That's it.  This happens all the time that we may type something wrong. The important thing is to identify it. :-) Feel free to give any suggestions :)

Expandable Arrays in C : behind the code

Arrays. They are beautiful. In C, we always try to work through restrictions arrays have i.e the size of the array must be statically defined. We always want a dynamic array whose size can be decided at run-time. There are ways which we use widely for e.g by using pointers and then dynamically allocating memory to it using malloc or calloc. But depending on the situation, we might require more efficient and organizable ways. I will explain the concept with a series of examples as in how simple arrays evolved to the tricky expandable ones. The classic way is to use pointers This snippet will allocate a memory block of size = array_size(integer array). Though this is not what I wanted to explain because this way is too clumsy. Imagine if you need 10 dynamic arrays in your program, you have to write these four lines each time and you have to keep track of all the 10 sizes. A better way is to use structures: We can simply create a structure containing two elements: array_size and...

ssh: Could not resolve hostname git: No address associated with hostname

I came across this error when I needed to clone a git repo. I tried few times but I couldn't get it working. There were few suggestions on the internet, but none resolved my issue. So, lets get to the point, this issue may occur due to following reasons: 1. If you are using proxy to access git and it is not properly configured/proxy is not allowing you access git due to permission issues. More here: git-clone-no-address-associated-with-name getting-git-to-work-with-a-proxy-server 2. This happens due to a silly mistake. [I do make silly mistakes sometimes] Are you actually using git clone for cloning? I used this - ssh git@github.com:neovim/neovim.git instead of git clone git@github.com:neovim/neovim.git ----- Hope this have resolved your issue :-) Happy Coding.