Debugging Guidelines

Before You Stop by Office Hours

  1. Incremental Code Development - You should be developing your code using incremental code development. That means that you add a little bit of code and verify it works before moving forward. If you stop by during office hours looking for assistance with your code, the first thing we will ask you is up to what point your code was working. If you cannot answer that question, we will not be able to help you.
  2. Tools - Make sure you have run splint (e.g., splint my_code.c) and valgrind (e.g., valgrind a.out) on your code.
  3. Segmentation Fault? - If your code is generating a segmentation fault, run the debugger (gdb) and use where to identify where the fault is taking place.
  4. Simplify Input - Simplify the input that is causing the code to fail. This will help you find the problem and if you need to see us, help us locate the problem with your code.

Approach to Write Code

If you are careful and follow some guidelines, the amount of debugging you need to do is minimized. The guidelines are:

  1. Incremental code development - Write a little bit of code and verify it works before moving forward. How much is a little bit depends on your coding experience.
  2. Good variable names and indentation from the beginning - Do not wait until submission time to fix indentation and variable names.
  3. Keep backups - You can use the submit server as a backup mechanism.
  4. Do not make assumptions - If you are not sure how a language construct works, look up information about it or write a small program that allows you to understand it.
  5. Use Tools Often - Check your code with splint, valgrind, and the additional gcc flags mentioned below often. Do not wait until you have a lot of code to use the tools. Do not wait to have a bug in order to use them.

Debugging Strategy

          1. Use splint to identify any problems.

          2. Make sure your gcc alias has been set correctly.  

          3. Compile your code with gcc flags -fmudflapth -lmudflap as they can provide additional information. 

             gcc flags -fmudflapth -lmudflap my_code.c

          4. Run valgrind on your code (see usage information below).

          5. if (segmentation fault) {
                Use gdb and the where command.
             } else {
                if (no results) {
                   a. Program may have an infinite loop (check your loops).
                   b. Program is waiting for input.
                   c. Output statements failed.
                } else {
                   /* incorrect results or different in the submit server */
                   a. Use the diff command to identify the differences.
                   b. If using diff does not help, simplify the input as much
                      as possible to see if you can identify the problem.
                   c. Step through the code using the debugger.
                   d. If all the above fails, use printf statements to see 
                      values, and the execution path leading to the problem.
                }
             }
       

Using valgrind

The valgrind utility is mainly use to detect dynamic memory problems, but it can also be used to detect invalid memory accesses. To use the utility:

valgrind a.out

If you are using input redirection:

valgrind a.out < public01.in

Other options:

valgrind a.out

valgrind --leak-check=full a.out /* for details of leaked memory */

valgrind --track-origins=yes a.out /* to track use of uninitialized values */

Typical Problems

  1. You get the correct results in grace, but not in the submit server - This may happen because:

Web Accessibility