Design and Debugging¶
约 363 个字 17 行代码 预计阅读时间 2 分钟 共被读过 次
15-213/15-513: Introduction to Computer Systems
8th Lecture, Sept. 19, 2024
Instructors: Brian Railing, Mohamed Farag
📚 After This Lecture, You Will Be Able To:¶
- Describe the steps to debug complex code failures.
- Identify ways to manage complexity when programming.
- State guidelines for communicating the intention of the code.
📝 Outline¶
Debugging¶
- Defects and Failures
- Scientific Debugging
- Tools
Design¶
- Managing Complexity
- Communication (Naming, Comments)
🛠 Debugging¶
Defects, Errors, & Failures¶
- Defect: Programmer creates a fault.
- Error: Defect causes wrong results in data/control signals.
- Error Propagation: Erroneous state spreads.
- Failure: System/component fails to produce intended result.
🔍 Why errors ≠ failures?
Errors can be masked (e.g., ECC memory) or detected.
🧪 Scientific Debugging¶
- Hypothesis: Propose a defect explanation.
- Prediction: What happens if the hypothesis is true?
- Experiment: Test under controlled conditions.
- Observation: Collect data to confirm/refute the hypothesis.
- Fix & Confirm: Apply fix and validate.
Example: Atlas-Centaur Rocket Failure¶
- First Failure: Clogged turbopumps due to plastic remnants.
- Fix: Bake off plastic.
- Second Failure: Leaking valve pushed to failure by efficiency demands.
- Lesson: Reproduce the failure to diagnose.
🐛 Code Example: Buggy Fibonacci¶
C
int fib(int n) {
int $f, f 0=1, f 1=1$;
while $(n>1)$ {
$$n=n-1;$$
$f=f 0+f 1$;
$f 0=f 1$;
f1=f;
}
return $f;
}
Failure:
fib(1)
returns garbage (e.g., 134513905
). 🔍 Hypothesis Table¶
Code Snippet | Hypothesis |
---|---|
while(n>1) | Loop condition incorrect for n=1 |
int f; | f is uninitialized |
🛠 Fix: Initialize f
¶
🧪 Experiment Results¶
- Without Fix:
fib(1) = 0
(uninitialized value). - With Fix:
fib(1) = 1
(correct).
🛠 Tools for Debugging¶
- Compiler Flags:
- Valgrind: Detect memory leaks/uninitialized accesses.
- GDB: Step-through execution to trace state.
🎨 Design¶
Managing Complexity¶
- Techniques:
- Separation of Concerns
- Modularity
- Abstraction
- DRY (Don’t Repeat Yourself)
Example: Cache Access Steps¶
- Convert address → tag, set index, block offset.
- Look up set.
- Check tag match.
- Handle hit/miss (evict LRU, load new line).
📛 Naming Guidelines¶
- Avoid meaningless names:
- ❌tmp
,data
,foo
- ✅employeeSalary
,cacheLine
- Use domain terms:
- In a cache lab:line
,tag
,setIndex
. - Limit word count:
- ❌arraysOfSetsOfLinesOfBlocks
- ✅cache
💬 Comments¶
- Don’ts:
- ❌ Explain what code does (
i++ // increment i
). - ❌ Apologize for bad code.
- Dos:
- ✅ Explain why (e.g., magic numbers):
📊 Summary¶
- Debugging: Systematic hypothesis-driven process. ✅
- Design: Manage complexity via modularity, naming, and clear communication. 📦
- Tools: Use
-Wall
, Valgrind, and debuggers to catch issues early. 🛠
"Testing shows the presence, not the absence, of defects." – Dijkstra
🔗 Resources:
- The Space Review: Atlas-Centaur Failure
- Computer Systems: A Programmer’s Perspective, 3rd Ed.