Session 04: Memory Debugging¶
This session is about finding memory bugs, and picking the tool that matches the symptom.
- Breakpoints, watchpoints and backtraces with
gdb. - Invalid reads and writes, and leaks, with Valgrind.
- Recognising common bug patterns, from integer underflow to off-by-one allocation.
- Diagnosing a bug from a compiled binary, with no source code.
Learning objectives¶
By the end of this session you should be able to:
- Use
gdbto set breakpoints and watchpoints, inspect variables, and read a backtrace. - Use Valgrind's Memcheck tool to locate invalid reads and writes, and memory leaks.
- Recognize common bug patterns: unsigned integer underflow, dangling pointers after
realloc, uninitialised memory, broken linked-list removal, and off-by-one buffer allocation. - Choose the right tool from the symptom, and explain what each tool is blind to.
Prerequisites and required tools¶
- Session 03 concepts: heap allocation with
malloc/realloc/free, and ownership of a heap block. - A Linux environment with
gcc,make,gdbandvalgrindinstalled. - For the binary-only bonus exercise:
objdump,nm,readelfand Python 3.
Check that your system has all it needs for the lab, by downloading and running the check-prerequisites.sh script:
wget http://raw.githubusercontent.com/cs-pub-ro/operating-systems/refs/heads/main/scripts/check-prerequisites.sh
chmod a+x check-prerequisites.sh
./check-prerequisites.sh
The script installs nothing. It reports what is missing and prints the command that installs it on your distribution.
If something is missing, be sure to install and configure it.
Getting the lab archive¶
Download 04-memory-debugging.zip, then unzip it and change into the directory it creates:
wget https://github.com/cs-pub-ro/operating-systems/raw/lab-archives/04-memory-debugging.zip
unzip 04-memory-debugging.zip
cd 04-memory-debugging/
Work inside that directory for the rest of the session.
Task order¶
The demo comes first, solved together with the teaching assistant. The core exercises are then solved individually or in teams, in the numeric order shown. Bonus exercises are optional: start them if you finish the core exercises, or take them home.
| Order | Task | Type | Objective |
|---|---|---|---|
| 1 | demo-in-memory-database |
Demo | Fix three bugs — a crash, a wrong answer, and an invisible leak — with gdb and Valgrind. |
| 2 | 01-grade-histogram |
Core | Find an out-of-bounds write that Valgrind cannot see, using a watchpoint. |
| 3 | 02-longest-word |
Core | Find a memory leak in a program whose output is already correct. |
| 4 | 03-symbol-hash-table |
Core | Find three independent bugs in a hash table, choosing the right tool for each. |
| 5 | bonus-json-parser |
Bonus | Find a one-byte heap overflow that never changes the output. |
| 6 | bonus-binary-issue |
Bonus | Locate and patch a stack overflow in a compiled binary, with no source code. |
The demo teaches the workflow every exercise afterwards assumes: run it, watch how it fails, pick the tool that matches the failure, and walk back to the line. The two ideas to carry through the whole session are that the symptom tells you which tool to reach for, and that a clean run — even a correct-looking one — is not a proof of correctness.
Each exercise directory has a README.md with the task itself.