CS 3 (Spring 2022) Lab 02: C Debugging

This lab will introduce you to asan, which is a tool that you can use to help debug your C code. It also asks you to write an example program which will demonstrate the usefulness of asan.

Setup

Register for the lab using grinch: https://grinch.caltech.edu/register and clone the repository as explained in the setup instructions.

A New Debugging Tool: asan

As you’ve already seen, clang is a C compiler. What you might not know is that it has a bunch of built-in libraries which can be useful when debugging.
One of the most useful is called asan. asan will provide a stack trace when your program crashes instead of just spitting out Segmentation Fault.

Buggy Program #1

Consider the following (obviously) buggy program (which is dumb1.c in your repository):

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char *dumb = NULL;
    dumb[0] = 'x';
}

What will happen when dumb1.c is compiled and run?

Try it!

Run the command:

clang -g dumb1.c -o dumb1
./dumb1

Welcome to the wonderful world of C debugging! We got absolutely no useful information about what went wrong; however, to “debug” it, we need to start somewhere. This is where asan comes in.

Add the flag -fsanitize=address (which means “turn on asan”) to the compilation line. Then, run the program.

This time, instead of the unhelpful Segmentation Fault message, asan tells us we have an error related to a “WRITE memory access” and that “address points to the zero page”. In other words, we’re assigning (writing) to a NULL pointer, which is exactly what’s happening. It may seem obvious in this case, but in more complicated programs, it can sometimes be totally non-obvious why or where the segmentation fault occurs.

Buggy Program #2

Now consider this (slightly) less dumb program (which is dumb2.c in your repository):

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char *dumb = malloc(1);
    dumb[0] = 'x';
    dumb[1] = 'y';
}

What will happen when dumb2.c is compiled and run with normal clang? What is the bug in the program?

This one is slightly more subtle, because it may have executed without error. This is called “undefined behavior”, and we should NEVER rely on it. What has happened here is that we’re modifying someone else’s memory–which will sometimes result in a segmentation fault, but sometimes will just silently corrupt some random other memory or variable, or do something else unpredictable.

What will happen when dumb2.c is compiled and run with -fsanitize=address? What is the bug in the program?

asan spits out a rather long error message which seems useless at first, but let’s look at the two top blocks:

WRITE of size 1 at 0x6020000000d1 thread TO
...

and

0x6020000000d1 is located 0 bytes to the right of 1-byte region (0x6020000000d0, 0x6020000000d1)
allocated by thread T0 here:
...

asan is telling us that we are illegally trying to assign a single byte in main, and that it’s located to the right of the memory also allocated in main.

Buggy Program #3

Finally, consider this (still) buggy program (which is dumb3.c in your repository):

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char *dumb = malloc(2);
}

What is the error this time? (Hint: The program definitely won’t crash.)

This program leaks memory! We called malloc, but we didn’t call free. On Linux, -fsanitize=address will tell you about memory leaks. Unfortunately, you can’t get support for that on Windows or Mac easily.

Writing one more C String Function

In CS 2, you probably used the split method on Strings a lot. In this lab, you will write a simplified version of this method for C Strings.

Getting Checked Off

Labs will be due the following Tuesday from when they are assigned, at 11:30 PST. You will need to get manually checked off for most labs, as we will not be using totally automated tests. To get checked off, make a ticket saying you are done, and we will check you off as soon as possible. Please include the link to your repo in the ticket.