Lab 9: Introduction to GDB

CS 3410 Spring 2018


Due: Show your completed text file to your TA by the end of section for credit.


GNU Debugger AKA GDB

GDB is an incredibly useful tool for debugging C code. It allows you to see where errors happen and step through your code one line at a time, with the ability to see values of variables along the way. Learning how to use GDB effectively will be very important to you later on in this course, particularly for the final project. To teach you to use this tool, you'll be debugging a selection sort implementation. You are already familiar with selection sort, as you implemented it in the previous lab, so we hope that you can focus your time on learning GDB as you already are familiar with the algorithm.
  1. Make sure you're using the Ubuntu environment we provide for you! This is one of those assignments that may perform differently on different systems.
  2. Retrieve the lab 9 files from Github with git pull in your CS 3410 Github repository.

Part 1

Before we start with GDB, we need some test cases to run our selection_sort on. In function main, initialize an array and call the selection sort function with that array as an input.

** Note: The implementation of selection sort takes in an array of longs, not integers, so make sure to create your array with longs. Longs are a data type in C which have at least 32 bits. Most computers today represent longs with 64 bits, giving you the ability to represent bigger numbers easily.

In previous labs, we simply compiled the code, and ran it. Let's do this, hoping that that our code compiles and runs properly. For reference, to compile buggy_sel_sort.c type gcc -std=c99 -Wall -Werror buggy_sel_sort.c -o lab9. To run the executable, type ./program_name (Our gcc command included -o lab9, which makes the program name in this case lab9).

Oh snap! It doesn't work, it segfaulted! A segfault occurs when your program tries to access memory, either by reading or writing, which it is not allowed to. Let's use GDB to find out where this occurs.

Part 2

This time, compile the buggy_sel_Sort.c file with the -g flag. This flag will add debugging symbols to the executable that will allow GDB to debug much more effectively. Do this by running gcc -g -std=c99 -Wall -Werror buggy_sel_sort.c -o lab9.

To begin debug with GDB type gdb program_name. This will present you with the GDB Prompt.

To run your executable in GDB, type run. This command runs your program until a breakpoint or crash is encountered. You can also pause your program by pressing Contrl-C (useful for finding infinite loops). When one of these is encountered, you will be able to inspect the state of your program with any of the following commands.

When GDB reaches an error, it will only tell you the line of code that it fails on. In order to see the whole backtrace, the whole set of stack frames associated with the file at the time, type backtrace. Use this the function that called the function that failed. buggy_sel_sort.c:linenumber tells you the file and line number that the error occured it.

You should also see multiple lines that look like swap (a=0x3, b=0x1) at buggy_sel_sort.c:29 which tell you the function, the line number, and its arguments, indicating that the function call occured.

Alternatively we can see the value of a using the command print a. This prints the value of expression or variable a at the current line of execution.

Is something wrong with a? In your text file, in a section called Bug 1:, explain the problem with a's value, and what it should actually be. Then fix this bug in the file, and test that it doesn't segfault.

Part 3

If we want to stop and see what is going on at a particular point in our program, we can use breakpoints. To do this in GDB, type break buggy_sel_sort.c:41, to set a breakpoint on line 41 of file buggy_sel_sort.c. To execute line by line from this point, we can step. Step executes one line of code, and will move into a function if that line is a function. next will execute one line of the current function, without stepping into other function calls.

If given:

functionB(){		
	int j = 2;		
	int k = 3;		
	return k;
}

functionA(){
	int i  = functionB();
	return i;
} 
If we are at line int i = functionA(); , step will go to int j = 2; whereas next will move to return i

Type next to progress to the next line, and type print swap_idx to look at its value. Type continue to go to the next time the breakpoint is hit, which will be the next iteration of the loop.

Notice how the value of swap_idx doesn't reflect that actual value that it should be. Continue using gdb to step through the code until you know what the bug is, and fix the bug.

Is something wrong with swap_idx? In your text file, in a section called Bug 2:, explain the problem with swap_idx's value, and what it should actually be in the code. After fixing the bug, test that the error doesn't appear again.

Part 4

Using your newly acquired gdb debugging skills, use a combination of the gdb commands you've learned thus far to find and fix the last bug. In your text file, in a section called Bug 3: explain the bug, and fix it.

Check Off

Be sure to demonstrate to your TA that you understand all the bugs in the code by explaining your text file.