Lab 6 - Pair Debugging

Prerequisite Skills for This Lab


  • C Skills
    • Able to work with a C linked-list.
    • Able to create and use structs.
    • Able to use pointers: type cast, dereference, pointer arithmetic.
    • Able to compile, run, and debug C programs.
  • Debugging Skills
    • Able to effectively use the debugger cdbg.
    • Understand use of assert for checking what should be true as a program executes.


Task 1: Debugging with the Debugger


  1. Create a folder for Lab 6 in your cmpt201 docker container with these Starter files:
    • example_1.c
    • example_2.c
    • CMakeLists.txt
  2. Find a partner to work with (highly recommended, but not required).
  3. Run example_1.c and see the error:
    1. Read and run example_1.c; observe the error.
    2. Use cmake to generate a debug build (-DCMAKE_BUILD_TYPE=Debug)
      • Ensure you are using the correct CMake command to create the build scripts:
        cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
        cd build
      • Each time you make a change to your program, you just need to build and run:
        make ./example1 or use debugger cgdb ./example1
      • Suggestion: Have two terminals open: one in the build/ folder to run your program, the other with nvim editing the files.
  4. Use cgdb to debug the program. Insert breakpoints and step through the code
    • Hint - cgdb Commands You'll likely need commands like: d main, s, c, print head.
    • Hint - View state As you step through the program, print the state of variables to see what has happened, and what will happen next.
  5. Change the example_1.c file to correct the bug(s).

Task 2: Debugging with Assertions


  1. With a partner, investigate example_2.c
    • Read and run example_2.c.
    • Did it run without error? Check the code to see what tests are currently in the code. There is a bug though!
  2. Write a function which iterates through the list and returns the sum of all elements in the list.
  3. Add an ASSERT() statements at the end of main() to check that the info.sum value equals what your sum function is returning.
    • This sum is called a side property:
      The code already calculated the sum, and now you have written a second way to calculate it.
    • Run the program; it should now fail your assert.
  4. Before debugging the problem, let's improve the ASSERT() macro to also display the file and line number where the assert fails.
    • In C, the macro __FILE__ and __LINE__ expand to be the file name and line number of the line where they are.
    • Add a new fprintf() statement inside ASSERT() to also print out the current file and line info.
    • Note that since ASSERT() is a macro, it gets expanded in the original code, and hence __LINE__ will be the line number of the ASSERT() call, not the line number where the ASSERT() macro is defined.
    • Hint - Slash You'll need to add a `\` at the end of the new line in your macro to make the macro all one line.
    • Hint - Types __FILE__ is a string ("%s") and __LINE__ is an int (%d).
  5. Add assertions to find the bug in example_2.c.
    • Hint - Placement Add the call to ASSERT() somewhere so that it checks the sum is updated correctly after items are added to the list.
    • Hint - Debug Once you know when the bug happens, try using the debugger to step through and watch what is going wrong.
  6. Change the example_2.c file to correct the bug; leave your assertions in place.
  7. When done, help others.


3. Reviewing (10 mins)


  • During the last 10 minutes of the in-person lab, TAs will walk through debugging these issues.
  • Discussion Points
    • How can cgdb be used to see the state of the program as it runs.
    • Talk through stepping through the program and looking at its state.
    • What is the bug?
  • Now that you have seen the solution:
    • Ensure you can debug the programs using the expected tools. Not just can you see the bug, but you should be comfortable with the tools.
    • Finish correcting your solution: don't just copy the solution, but it is OK if you use the ideas you saw to help you finish.


4. [Optional] Challenges


  1. Optional: Create a new macro named ASSERT_EQUALS() which takes in three arguments: expected value, actual value, message.
    • Make it do the similar functionality as ASSERT() except it can print out the values it is handed.
    • Update your code to use this instead. Recreate the original error; does the ASSERT_EQUALS() help debug the problem?
  2. Optional: Test the performance impact of adding the asserts to your code.
    • Change example_2.c to add a large number of elements to the array.
    • Disable your asserts and then time your program running use time ./example2. Run the program 5 times recording how long it takes.
    • Hint - Disable You can replace your ASSERT() macro with a blank one: #define ASSERT(exp)
    • Re-enable your asserts and run the program again 5 times and compare how long it takes with and without the asserts.


Submission


Create a single lab6.c file which copies in the entire contents of your corrected example_1.c and example_2.c (with or without the optional components). The program won't run, but we are just looking at the solution to see if you corrected the bugs and added assertions. Leave your assertions in the task 2 code.

Submit your C code to CourSys by Sunday midnight. The file name must be an exact match to what CourSys is expecting, otherwise it won't accept it. Remember you can submit up to 3 days late with no penalty if needed (but please plan to get it done on time to stay up to date on the course!)

Submissions will be marked for completion. You do not need to complete any optional steps.