Lab 9: Introduction to GDB

CS 3410 Spring 2017

Due: Sunday, April 2, 2017 at 11:59 PM. Submit all required files on CMS.

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 simple program that determines if a string is a palindrome. The palindrome program takes in a single argument, and outputs whether or not the argument is a palindrome, ignoring case and non-alphanumeric characters entirely (it should act as if they are not there - this means a string like 'A man, a plan, a canal -- Panama!' should be a palindrome). But it's broken! Here's a crash course on GDB to get you started. We'll give you a failing edge case and help you find the bug, but you're responsbile for fixing the bug.
  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, and we will not accept regrade requests if it works on your system but not on ours.
  2. Retrieve the lab 9 files from Github with git pull in your CS 3410 Github repository.
  3. Compile the buggy_palindrome.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_palindrome.c -o lab9.
  4. Play around with the program a couple times - remember you can run executables with ./program_name. Try putting in a couple arguments, like ./program_name abba or ./program_name abca Before you proceed in the lab, see if you can figure out for what strings the palindrome doesn't work.
  5. Now run the program with gdb program_name. This will come up with the gdb prompt
  6. Type run to run the program. To provide it arguments while in gdb, type run args, e.g. run 'racecar'
  7. Now, you'll want to find a case where the program fails. One case where the program fails is for the argument %racecar% -- this string is clearly a palindrome but the program will report that it isn't one. Use this edge case in the next steps but also try to find other edge cases on your own!
  8. In order to see how the program is working, we'll want to step through it slowly. For debugging much larger programs (which you will inevitably have to in future projects in CS, starting with this course!), there is always the question of how to start and where to start. Usually you want to start debugging a program by putting a breakpoint at a crucial point in the code where you know it starts executing. This could be in the main program or in a specific function that you know is buggy. In GDB, you can put breakpoints at functions or at line numbers.

    For example you could put a breakpoint like break main and this would put a breakpoint at the main function in the file. Or you could put it at a specific line number that you know the program gets stuck on. But to start debugging, the best place to start is often at the main point of execution, and then stepping through the code and placing more breakpoints to further narrow down the problematic area.

    For the purpose of this lab we're going to tell you where exactly to put the breakpoint and how to debug, but keep in mind it figuring out where exactly the problematic code won't always come easily when debugging programs. Type break 29 to add a breakpoint on line 29 - now when you run the program, it will pause every time execution reaches line 29. Type run '%racecar%' to start debugging. You should see the following:

    (gdb) run '%racecar%'
    Starting program: /home/james/3410/cs3410-2016fa/labs/lab9/lab9 '%racecar%'
    String: %racecar%
    Breakpoint 1, is_palindrome (s=0x7fffffffdbd0 "%racecar%")
        at buggy_palindrome.c:30
    30          if(c1_char != c2_char) {
  9. Now you can print out the values of any variables you'd like, or expressions. Type print c1 to see the value of c1, or print c1_char. You can even type expressions like print 1 + 1
  10. To continue navigating through code, you have 3 main options:
    • continue will continue execution until the program ends or reaches another breakpoint
    • next will jump to the next line that the program executes, but will not jump into function calls
    • step will step to the next line that the program executes, including stepping into function calls
    • quit will quit GDB - you should do this every time you recompile, otherwise you will not see your changes
  11. The rest is up to you now. Using your newfound knowledge of GDB and fix the bug. Remember that the resulting program should follow the spec given i.e. it should say whether or not a string is a palindrome ignoring all special characters. Fix the program and submit your fixed palindrome file onto CMS. Your edits should not do anything other than change when the is_palindrome function returns true or false - there should be no additional output.

    Tip: Don't necessarily just look for a quick one line fix. It's not impossible to fix in one line but it's definitely easier if you don't constrain yourself to a one line change.

Some Additional Tips