C Segmentation Faults

Published on February 6th, 2013 | by Vaibhav

1

Segmentation Faults and Memory Errors

You must have experienced segmentation faults. No? Then you haven’t done much of programming using pointers! Usually, we have compile time errors which are easy to solve, but fixing run-time errors can be tedious job. Among the latter, segmentation faults are most common, arising while using pointers in C/C++. Let us first have a brief idea about it.

Just as variables have some unknown value before initializing, pointers also point to some unknown locations in the memory, which may be beyond the access of the program memory. Mainly seg-faults arise due to dereferencing of such pointers, commonly known as dangling pointers (pointers which have not been initialized, and hence dangling). It may occur in the following scenarios:

Writing/accessing array elements for indices out of range, like accessing value at the index 20, for the array which is declared as a[10].

  • Trying to reference/dereference uninitialized pointers.

  • Trying to access a pointer that has already been freed.

  • Passing invalid buffers for reading/writing to functions/system calls.

Though such memory errors can be checked for in small programs, it is troublesome to do the same in codes that span over hundreds and thousands of lines. They are also dangerous in critical systems like emergency and safety systems.

The GNU Project Debugger (GDB) and Valgrind are some of the tools which can be used to debug and fix errors in code. The former being a debugger, the latter is a memory checker. GDB can be used to step interactively through the program, allowing us to see what is going on inside the program during its execution. Valgrind, an open source tool, can be used to dynamically execute the program. Let us get a hands-on experience with Valgrind, withouh getting into details of its working.

For demonstration purposes, I have written the following code in C.

#include <stdlib.h> int main() {     int *ptr = malloc (sizeof (int)*10);     return 0; }

The code is compiled, adding some debugging information, as shown:

gcc -g code1.c -o code1

(See man page of gcc for further details on the ‘-g’ option)

Now the code is run using Valgrind as shown:

valgrind ./code1

Running the code gives the output:

==4052== Memcheck, a memory error detector

==4052== Copyright (C) 2002-2011, and GNU GPL’d, by Julian Seward et al.

==4052== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info

==4052== Command: ./code1

==4052==

==4052==

==4052== HEAP SUMMARY:

==4052== in use at exit: 40 bytes in 1 blocks

==4052== total heap usage: 1 allocs, 0 frees, 40 bytes allocated

==4052==

==4052== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1

==4052== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)

==4052== by 0x80483F8: main (code1.c:5)

==4052==

==4052== LEAK SUMMARY:

==4052== definitely lost: 40 bytes in 1 blocks

==4052== indirectly lost: 0 bytes in 0 blocks

==4052== possibly lost: 0 bytes in 0 blocks

==4052== still reachable: 0 bytes in 0 blocks

==4052== suppressed: 0 bytes in 0 blocks

==4052==

==4052== For counts of detected and suppressed errors, rerun with: -v

==4052== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Analysing the output:

The number on extreme left shows process ID (4052) of the program. The output is divided in three parts viz., Heap Summary, Leak Summary and Error Summary.

Heap Summary:

This part provides information of calls to functions allocating and freeing memory. It also shows amount of memory still in use at exit of the program. If the total number of allocs and frees do not match, a memory fault is indicated. The line number for error is also specified (eg: code1.c:5)

Leak Summary:

This part provides details of the amount of memory leaked and its different categories as shown above.

Error Summary:

This summarizes the entire analysis providing with the number of errors.

Let us consider some other scenarios:

1. Referencing array elements which are out of range

Add following lines to the above code:

    ptr[10] = 10;

The output is:

==5555== Invalid write of size 4

==5555== at 0×8048404: main (code1.c:6)

==5555== Address 0x41f8050 is 0 bytes after a block of size 40 alloc’d

It indicates that an invalid write of size 4 bytes is happening at address 0×8048404, i.e. at line 6 in the main function of the program. This can be used to analyse the error in detail.

2. Dereferencing a dangling pointer

Add the following lines to the code:

if (ptr[1] == 0)

    printf (“zero”);

(You will have to include the header file stdio.h.)

Output is as shown:

==5910== Conditional jump or move depends on uninitialised value(s)

==5910== at 0×8048438: main (code1.c:6)

Though Valgrind does not report uninitialised data, it reports an error when such data is used in program.

You can explore and analyse other scenarios in a similar fashion using Valgrind. This can help greatly to optimize codes for large applications and helps us to avoid garbage memory during code execution. Note that C/C++ does not have any garbage collector to collect unused memory, like Java.

Software details:

gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, Valgrind v3.7.0.

Valgrind is available in the ubuntu repositories. Install the latest version by using:

sudo apt-get install valgrind

Alternately get it here: valgrind.org/

Try this out:

Run your codes dynamically using Valgrind and check if all the allocated memory is returned to the system before exiting the program.

Also explore other options for Valgrind by reading the man page for Valgrind.

Tags: , , ,


About the Author

Vaibhav is an free software enthusiast and likes to try out new things in the free software world. When he is not working on a computer, he likes to play games like chess and badminton.



One Response to Segmentation Faults and Memory Errors

  1. Rishikesh Chavan says:

    Thanks ….i found this post very useful in my project work….

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Back to Top ↑