Week 6: GDB

For this lab, we're working with GDB.  Get into groups of 2-4, then debug some buggy programs!
 
If you want to get tricky on any of these, you can also use reversible debugging (introduced in GDB 7).  To start, say "target record" after running the program.  I usually do the following:

b main

r

target record

After that, you can use rn (reverse next), rs (reverse step), or rc (reverse continue).  This way, you can still do stuff after hitting a segfault.
 
PART 1: Buggy Programs
 
First, download the programs.  Go into your command line and then download  http://stanford.edu/~lao793/cs1u/buggy-code.tar.gz -- to download a file given a URL, you can use wget someUrlThatYouWantToDownload. wget apparently isn't installed by default on macs, so there you can use curl someUrl > someFile.  the > sign redirects standard output to a file.

This is in the tar format, a very common format for grouping a bunch of files together.  It's like a zip file.  To create this tar file, we used tar with the -c (create) flag:
    tar -czf broken-programs.tar.gz prog[1-7].c
(note: prog[1-7.c] uses a regular expression that zsh will expand to prog1.c prog2.c prog3.c …)
To extract these files, you need to untar broke-programs.tar.gz.  You can use

    tar -xvzf someTarFile

to extract (x) and display verbose (v) information from a gzipped (z) file (f).  If the file is not gzipped (ie, the format ends in .tar rather than .tar.gz), you will need to use tar -xvf rather than tar -xvzf.

Note: the Makefile might break if you don't have 32 bit headers installed and are using a 64 bit system.  You can either change the makefile out of 32 bit mode or you can manually use GCC to compile it.  32 bit mode, however, might help expose some of the bugs.  The Myth machines have 32 bit headers installed.

To compile something where there isn't a makefile, you can use something like

    gcc -g -o outputFile myProgram.c

where -g adds debugging symbols, -o says that you want to name the output file, and you also need to provide the input c file.  Alternately, you can make a makefile for yourself.

For each program, run it in GDB, figure out what went wrong, and fix it!  

PART 2: More Common Bugs

If you finish that early, there are some more programs from a previous iteration of the course available at https://practicalunix.org/static/old-buggy-code.tar.gz.  These programs don't have as much of a purpose and are more meant to demonstrate some common bugs.  See if you can find the bugs in GDB.

For these, there isn't a Makefile at all, so you're forced to manually compile them regardless of whether you're on a mac or not.

prog1-4 illustrate common bugs.  If you ever want to stop your program before it's done, you can use Ctrl+C to send a keyboard interrupt and interrupt your program.

prog5 - watchpoints and reversible debugging are your two best friends.
prog6 - changing the flow of the program is essential
prog7 - there are multiple issues.  With this one, you actually have to fix the code (without changing the general flow of the program).  The program should allocate num_words strings on the heap, put a string into that memory, print them, and free all allocated memory.
  
PART 3: Your Programs
 
Still in your groups, spend a few minutes coming up with logical errors and write a program that features them (think Obfuscated C Code Contest).  Since we are emphasizing GDB, not GCC, there should be NO compile time errors.  Ideally, your program should emphasize a particular feature of GDB.  You should probably spend about 10 minutes brainstorming and 10 minutes writing your code.
 
Next, put your code online. If you put anything in your WWW directory in your AFS space, it is online at stanford.edu/~YourSUNetId/.  Ie, my stuff is at http://stanford.edu/~samking/.  Then, make a post in the discussion forum with a link to your code and any relevant instructions (ie, what will a working program do?  are there any particular GDB tools that will help debugging?).
 
Last, find another group that finished and debug their code.  The objective is to be the first person done with everyone else's code.

The rules of the contest:

1)  No malicious code.  

2)  Don't go beyond what a CS107 student should reasonably know.  It's okay to use other libraries as long as they have man pages and as long as they aren't too complicated.  That means no threads or embedded assembly, but it is okay to use stuff like the linked list macros or the hash map libraries.  

3)  It's encouraged to remove all line breaks and give variables non-descriptive names before submitting.  That means that it's to your advantage to know how to easily put line breaks back in.  It might help to peek forward to the grep replace video if you don't know how you would do this.

4)  It should be apparent what the program is supposed to do.  To facilitate this, you could have a non-obfuscated comment or printf at the start of main describing what is supposed to happen.

5) Try to write buggy code that helps to get at a lot of GDB's features (or a few of them very well).  There is a list of GDB commands at the bottom of each lecture.

6) Make sure that everyone in the group gets to contribute to the process.

7) Keep in mind that you won't have to debug your own code but other groups will.  That means that it's to your advantage to make the code that you write as difficult to debug as possible, within reason.

8) Please be aware that you are posting this code to a public discussion forum, which means that it shouldn't have anything from any class assignments or proprietary works.  People might even use it for future iterations of CS1U!