Project 4: The Corruption - Using Watchpoints
Find the exact instruction that corrupts memory using hardware watchpoints.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Intermediate |
| Time Estimate | 2-3 hours |
| Language | C (LLDB commands) |
| Prerequisites | Projects 1-3, pointer arithmetic |
| Key Topics | Watchpoints, memory inspection |
1. Learning Objectives
By completing this project, you will:
- Set a watchpoint on a variable or address.
- Trigger the watchpoint and identify the exact write.
- Understand hardware watchpoint limits.
- Use watchpoint conditions to reduce noise.
2. Theoretical Foundation
2.1 Core Concepts
- Watchpoint: Stops when memory at an address changes.
- Hardware watchpoint: Implemented by CPU debug registers.
- Memory corruption: Writes that change unrelated data.
2.2 Why This Matters
Watchpoints are the fastest way to catch “who wrote this” bugs. They are often the only practical way to find memory corruption in complex code.
2.3 Common Misconceptions
- “Watchpoints are unlimited.” (CPU hardware limits them.)
- “They always work on optimized code.” (Optimizations can move or eliminate variables.)
3. Project Specification
3.1 What You Will Build
A small program with an off-by-one write that corrupts adjacent memory. You will use a watchpoint to stop exactly at the write.
3.2 Functional Requirements
- Create a corruption bug.
- Set a watchpoint on the corrupted variable.
- Run until the watchpoint triggers.
- Identify the instruction that caused the corruption.
3.3 Non-Functional Requirements
- Precision: Watchpoint triggers on the correct write.
- Clarity: Notes include the offending line and why it corrupts.
3.4 Example Usage / Output
(lldb) watchpoint set variable local_value
(lldb) continue
3.5 Real World Outcome
$ clang -g -O0 -o corrupt corrupt.c
$ lldb ./corrupt
(lldb) b main
(lldb) run
(lldb) watchpoint set variable local_value
Watchpoint created: Watchpoint 1: addr = 0x7ffeefbff5ec size = 4
(lldb) continue
Process 7777 resuming
Watchpoint 1 hit:
old value: 200
new value: 0
* thread #1, stop reason = watchpoint 1
frame #0: 0x0000000100003f48 corrupt`buggy_function at corrupt.c:5
4. Solution Architecture
4.1 High-Level Design
Corruption -> Watchpoint -> Trigger -> Offending Instruction
4.2 Key Components
| Component | Responsibility | Key Decisions |
|---|---|---|
| Corrupting program | Produce off-by-one write | Simple pointer arithmetic |
| Watchpoint | Detect write | Variable vs address |
| LLDB analysis | Identify culprit | Backtrace + frame |
5. Implementation Guide
5.1 Development Environment Setup
clang -g -O0 -o corrupt corrupt.c
lldb ./corrupt
5.2 Project Structure
project-root/
|-- corrupt.c
`-- notes.md
5.3 The Core Question You’re Answering
“Who changed this memory, and what exact line caused it?”
5.4 Concepts You Must Understand First
- Pointer arithmetic
- Book: Understanding and Using C Pointers - Ch. 1-3
- Stack vs global memory
- Book: Computer Systems: A Programmer’s Perspective - Ch. 3
- Watchpoints
- Book: The Art of Debugging with GDB, DDD, and Eclipse - Ch. 5
5.5 Questions to Guide Your Design
- Which variable should you watch and why?
- How do you confirm the address being watched?
- How would you add a condition to only stop on specific values?
5.6 Thinking Exercise
Draw the memory layout around global_value and local_value. Predict where the bad write lands.
5.7 The Interview Questions They’ll Ask
- How are watchpoints implemented in hardware?
- What is the difference between a read and a write watchpoint?
- Why might a watchpoint fail to trigger?
- How many watchpoints can your CPU support?
5.8 Hints in Layers
Hint 1: Watch the corrupted variable
(lldb) watchpoint set variable local_value
Hint 2: Inspect the address
(lldb) frame variable &local_value
Hint 3: Add a condition
(lldb) watchpoint modify -c 'new_val == 0'
5.9 Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| Pointer arithmetic | Understanding and Using C Pointers | Ch. 1-3 |
| Memory layout | Computer Systems: A Programmer’s Perspective | Ch. 3 |
| Watchpoints | The Art of Debugging with GDB, DDD, and Eclipse | Ch. 5 |
5.10 Implementation Phases
Phase 1: Setup (30 min)
- Build the corrupt program and reproduce the issue.
Phase 2: Watchpoint (60 min)
- Set a watchpoint and trigger it.
Phase 3: Diagnosis (30 min)
- Explain the off-by-one bug and fix it.
5.11 Key Implementation Decisions
| Decision | Options | Recommendation | Rationale |
|---|---|---|---|
| Watchpoint target | Variable vs address | Variable | Clearer for beginners |
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Watchpoint trigger | Ensure it fires | Old/new value reported |
6.2 Critical Test Cases
- Watchpoint triggers on the corrupted write.
- Backtrace points to
buggy_function.
7. Common Pitfalls & Debugging
| Pitfall | Symptom | Solution |
|---|---|---|
| Watchpoint never hits | No stop | Rebuild with -O0, verify address |
| Too many watchpoints | Error or missing triggers | Delete unused watchpoints |
8. Extensions & Challenges
- Use a conditional watchpoint to stop only on certain values.
- Corrupt memory inside a loop and confirm multiple triggers.
9. Real-World Connections
- Memory corruption bugs in C/C++ are common in systems code.
- Watchpoints are a core technique used in security debugging.
10. Resources
- LLDB Command Reference: https://lldb.llvm.org/use/commandref.html
- LLDB Tutorial: https://lldb.llvm.org/use/tutorial.html
11. Self-Assessment Checklist
- I can set and trigger a watchpoint.
- I can explain why the write is corrupting memory.
- I can reduce watchpoint noise with conditions.
12. Submission / Completion Criteria
Minimum Viable Completion:
- Watchpoint triggers and shows the offending line.
Full Completion:
- You can explain the memory layout and fix the bug.
Excellence (Going Above & Beyond):
- You create a watchpoint on a raw address.
This guide was generated from LEARN_LLDB_DEEP_DIVE.md. For the full learning path, see the parent directory README.