Model Artifact: C Debugging Transcript
Scenario
A Semester 4 learner investigates a segmentation fault in a C line parser.
Completed learner-quality example
Symptom
parse_line("user:42") sometimes crashes in strlen during the second test run, but not when the test is run alone.
Hypothesis 1: caller passes a null pointer
Evidence: added an assertion at the public entry point. The failing run shows input != NULL, so this is not the immediate cause.
Hypothesis 2: token buffer is not null-terminated
Evidence from gdb:
(gdb) p token
$1 = 0x5555555592a0 "user:42¥¥¥"
(gdb) p len
$2 = 7
The token includes bytes past the allocated copy. strlen(token) can run beyond the allocation.
Root cause
The code allocated malloc(colon - input) for the username, copied that many bytes, and forgot space for \0. It also failed to write the terminator.
Fix
size_t name_len = (size_t)(colon - input);
char *name = malloc(name_len + 1);
if (name == NULL) {
return PARSE_OOM;
}
memcpy(name, input, name_len);
name[name_len] = '\0';
Verification
- Re-ran the focused parser tests 100 times.
- Ran the full test suite under AddressSanitizer.
- Added boundary tests for empty name, one-character name, and long name.
Lesson preserved
When copying a substring into a C string, allocate payload length + 1, write the terminator, and test the boundary where the payload length is zero.
How to read this example
- Passing: Shows symptom, hypotheses, evidence, root cause, fix, and verification.
- Strong: Uses debugger evidence instead of guessing and distinguishes disproven hypotheses from the final cause.
- Portfolio-worthy: Converts the debugging session into a reusable lesson and permanent tests.