Project 1: The Basics - First Steps
Build a tiny C program and use GDB to step, inspect variables, and understand control flow.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Beginner |
| Time Estimate | 1-2 hours |
| Language | GDB commands (C target) |
| Prerequisites | Basic C, compile with gcc -g |
| Key Topics | Breakpoints, stepping, stack frames, symbols |
1. Learning Objectives
By completing this project, you will:
- Compile a C program with debug symbols and understand why symbols matter.
- Control execution flow with
break,run,next, andstep. - Inspect variables, stack frames, and the call stack.
- Modify program state during a debug session.
2. Theoretical Foundation
2.1 Core Concepts
- Debug Symbols (DWARF): Symbol data maps machine addresses back to source lines and variable names. Without it, GDB can only show raw addresses.
- Stack Frames: Each function call creates a stack frame containing locals, arguments, and a return address.
backtracewalks these frames. - Breakpoints: GDB inserts a trap instruction (
int 3on x86) to halt execution at a chosen address.
2.2 Why This Matters
This is the minimum set of mechanics you need to make GDB useful on real bugs. Once you can stop, inspect, and continue, you can diagnose the majority of issues without adding logging.
2.3 Historical Context / Background
GDB dates to the 1980s and has remained the standard because it operates at the process and instruction level. These foundations predate modern IDEs and are still what IDE debuggers call under the hood.
2.4 Common Misconceptions
- “GDB needs source code”: It does not, but it is much less helpful without symbols.
- “next and step are the same”:
nextskips over function calls;stepenters them.
3. Project Specification
3.1 What You Will Build
A small C program with a loop and a function call. You will use GDB to control execution and inspect the program state at key points.
3.2 Functional Requirements
- Compile with symbols: Build using
gcc -g -O0. - Stop at main: Set a breakpoint and run to it.
- Step through the loop: Use
nextandstepto move in and out of functions. - Inspect state: Print variable values and view a backtrace.
3.3 Non-Functional Requirements
- Performance: Not applicable; this is a learning tool.
- Reliability: Debug session should be repeatable.
- Usability: Commands should be minimal and reproducible.
3.4 Example Usage / Output
(gdb) break main
(gdb) run
(gdb) next
(gdb) print i
$1 = 0
(gdb) step
(gdb) backtrace
3.5 Real World Outcome
You will see a complete GDB session in your terminal. Example output:
$ gcc -g -O0 -o target target.c
$ gdb ./target
GNU gdb (GDB) 14.1
Reading symbols from ./target...
(gdb) break main
Breakpoint 1 at 0x401160: file target.c, line 9.
(gdb) run
Starting program: ./target
Breakpoint 1, main () at target.c:9
9 {
(gdb) next
10 for (i = 0; i < 5; ++i) {
(gdb) print i
$1 = 0
(gdb) step
greet (count=0) at target.c:5
5 printf("Hello for the %dth time!\n", count);
4. Solution Architecture
4.1 High-Level Design
┌────────────┐ ┌─────────────┐ ┌──────────────┐
│ target.c │────▶│ gcc -g -O0 │────▶│ gdb session │
└────────────┘ └─────────────┘ └──────────────┘
4.2 Key Components
| Component | Responsibility | Key Decisions |
|---|---|---|
| C target program | Provide predictable control flow | Keep logic small and observable |
| GDB session | Control and inspect program | Use breakpoints and stepping |
4.3 Data Structures
struct FrameSnapshot {
const char *function;
int line;
long rip;
};
4.4 Algorithm Overview
Key Algorithm: Manual stepping loop
- Break at
main. - Execute one line at a time.
- Inspect locals and call stack at each step.
Complexity Analysis:
- Time: O(N) for N steps you take.
- Space: O(1) within GDB.
5. Implementation Guide
5.1 Development Environment Setup
gcc --version
gdb --version
5.2 Project Structure
project-root/
├── target.c
└── README.md
5.3 The Core Question You’re Answering
“How do I stop a program at a precise point and see what it knows right now?”
5.4 Concepts You Must Understand First
Stop and research these before coding:
- Debug Symbols and
-g- What is DWARF?
- Why do optimized builds hide variables?
- Book: “The Art of Debugging with GDB” Ch. 1
- Stack Frames
- What does a call stack look like?
- Why is the current frame at the top?
- Book: CSAPP Ch. 3
- Stepping Semantics
nextvsstepfinishvscontinue
5.5 Questions to Guide Your Design
- When should you use
stepinstead ofnext? - Which frame should you inspect to see function arguments?
- How do you verify the debugger is aligned with the source line?
5.6 Thinking Exercise
Trace the program on paper and predict i and count values at each greet() call.
5.7 The Interview Questions They’ll Ask
- What is the difference between
nextandstep? - Why does GDB show
<optimized out>sometimes? - How do you inspect the call stack?
5.8 Hints in Layers
Hint 1: Basic flow
break main,run,next,print i
Hint 2: Stack
backtrace,frame 0,info locals
Hint 3: Modify state
set var i = 10,continue
5.9 Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| GDB basics | “The Art of Debugging with GDB” | Ch. 1-3 |
| Stack frames | CSAPP | Ch. 3 |
| C functions | K&R C | Ch. 4 |
5.10 Implementation Phases
Phase 1: Foundation (30 minutes)
Goals:
- Build the target program with symbols.
- Start a GDB session.
Tasks:
- Compile with
gcc -g -O0. - Set a breakpoint at
mainand run.
Checkpoint: You stop at main and see source lines.
Phase 2: Core Functionality (30-45 minutes)
Goals:
- Step and inspect state.
Tasks:
- Use
nextfor loop iterations. - Use
stepto entergreet(). - Print locals and backtrace.
Checkpoint: You can explain where you are and what values exist.
Phase 3: Polish & Edge Cases (15-30 minutes)
Goals:
- Practice modifying state.
Tasks:
- Change
imid-run. - Observe altered output.
Checkpoint: Program reflects the modified value.
5.11 Key Implementation Decisions
| Decision | Options | Recommendation | Rationale |
|---|---|---|---|
| Optimization level | -O0, -O2 |
-O0 |
Keeps variables visible |
| Breakpoint placement | main, greet |
main first |
Establishes flow |
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Sanity checks | Verify debug symbols | file target shows debug_info |
| GDB usage | Confirm command workflow | break, run, print |
| State changes | Confirm modifications work | set var i = 10 |
6.2 Critical Test Cases
- Breakpoint hits:
break mainstops at line 9. - Stepping works:
stepentersgreet. - Variable inspection:
print ishows loop progress.
6.3 Test Data
Loop iterations: 0..4
Expected prints: 5 lines
7. Common Pitfalls & Debugging
7.1 Frequent Mistakes
| Pitfall | Symptom | Solution |
|---|---|---|
| No symbols | No line numbers | Recompile with -g |
| Optimization | <optimized out> |
Use -O0 |
| Wrong binary | Breakpoints not hit | Ensure correct executable |
7.2 Debugging Strategies
- Use
info filesto confirm symbols loaded. - Use
listto confirm source alignment.
7.3 Performance Traps
Not applicable at this scale.
8. Extensions & Challenges
8.1 Beginner Extensions
- Add a second function and step into it.
- Set a breakpoint by line number.
8.2 Intermediate Extensions
- Use
conditionon a breakpoint to stop ati == 3. - Inspect registers with
info registers.
8.3 Advanced Extensions
- Use
disassembleto inspect the loop. - Set a temporary breakpoint with
tbreak.
9. Real-World Connections
9.1 Industry Applications
- Production debugging: First response to a reported bug is often a GDB session.
- Embedded systems: Many targets only support GDB-like workflows.
9.2 Related Open Source Projects
- GDB: https://sourceware.org/gdb/ - The debugger itself.
- rr: https://rr-project.org/ - Record and replay debugging.
9.3 Interview Relevance
- Demonstrates understanding of call stacks and control flow.
- Shows you can debug without IDE crutches.
10. Resources
10.1 Essential Reading
- “The Art of Debugging with GDB” - Ch. 1-3 for fundamentals.
- GDB Manual - “Running Programs” and “Stopping and Continuing” sections.
10.2 Video Resources
- GDB basics walkthrough (search: “GDB basics break run step”).
10.3 Tools & Documentation
- GDB: https://sourceware.org/gdb/ - Official docs.
- gcc: https://gcc.gnu.org/ - Compiler documentation.
10.4 Related Projects in This Series
- Next Project: Core Dump Analysis builds post-mortem skills.
11. Self-Assessment Checklist
11.1 Understanding
- I can explain why debug symbols are required.
- I can describe what a stack frame contains.
- I can explain the difference between
nextandstep.
11.2 Implementation
- Breakpoints hit reliably.
- I can inspect locals and call stack.
- I can modify a variable and see the effect.
11.3 Growth
- I can describe a bug I could now diagnose faster.
- I can explain this workflow to someone else.
12. Submission / Completion Criteria
Minimum Viable Completion:
- Break at
mainand step intogreet. - Print
iandcountvalues. - Show a backtrace with two frames.
Full Completion:
- Modify
iduring execution and observe output changes. - Document the command sequence used.
Excellence (Going Above & Beyond):
- Add a second function and debug across both.
- Use a conditional breakpoint or watchpoint.
This guide was generated from LEARN_GDB_DEEP_DIVE.md. For the complete learning path, see the parent directory README.