Project 3: The Hang - Attach to a Running Process

Debug a live process by attaching GDB to a running program and detaching without killing it.

Quick Reference

Attribute Value
Difficulty Intermediate
Time Estimate 1 hour
Language GDB commands (C target)
Prerequisites Project 1, basic Linux process tools
Key Topics gdb -p, signals, detach, live state edits

1. Learning Objectives

By completing this project, you will:

  1. Locate a running process and attach GDB to it.
  2. Interrupt execution and inspect the current stack frame.
  3. Modify live process state safely.
  4. Detach cleanly and confirm the process keeps running.

2. Theoretical Foundation

2.1 Core Concepts

  • Process IDs (PIDs): Identifiers used to attach to an existing process.
  • ptrace attach: GDB uses ptrace to stop and control a live process.
  • Signals on attach: The target is stopped with SIGSTOP; you can send SIGINT with Ctrl-C.

2.2 Why This Matters

Production systems cannot always be restarted. Attaching to a live process is how you inspect and fix a hang without downtime.

2.3 Historical Context / Background

UNIX debugging tools have always supported process attachment because many services run long-lived. This feature is foundational for ops debugging.

2.4 Common Misconceptions

  • “Attach kills the process”: It does not; you can detach and keep it running.
  • “You need symbols for libs”: You can still inspect your own code with partial symbols.

3. Project Specification

3.1 What You Will Build

A C program that loops forever and sleeps. You will attach GDB to it, inspect state, modify a variable, and detach.

3.2 Functional Requirements

  1. Start a long-running process in one terminal.
  2. Attach GDB using gdb -p <PID>.
  3. Inspect call stack and local variables.
  4. Detach without killing the process.

3.3 Non-Functional Requirements

  • Reliability: Detach should not terminate the process.
  • Usability: Commands should be short and repeatable.
  • Security: Attach only to processes you own.

3.4 Example Usage / Output

$ ps aux | grep hang
$ gdb -p 12345
(gdb) backtrace
(gdb) print counter
(gdb) detach

3.5 Real World Outcome

You will see the running process pause and resume after detaching:

$ ./hang
Looping... counter = 0
Looping... counter = 1
$ gdb -p 23456
GNU gdb (GDB) 14.1
Attaching to process 23456
(gdb) backtrace
#0  __nanosleep () from /lib64/libc.so.6
#1  sleep () from /lib64/libc.so.6
#2  main () at hang.c:8
(gdb) print counter
$1 = 6
(gdb) set var counter = 100
(gdb) detach
Detaching from program: ./hang, process 23456

4. Solution Architecture

4.1 High-Level Design

┌────────────┐     ┌─────────────┐     ┌──────────────┐
│  hang.c    │────▶│  running PID│────▶│  gdb attach  │
└────────────┘     └─────────────┘     └──────────────┘

4.2 Key Components

Component Responsibility Key Decisions
Long-running target Provide stable attach point Sleep in loop
GDB attach Stop and inspect process gdb -p workflow
Detach Resume execution Use detach not quit

4.3 Data Structures

struct LiveState {
    int counter;
    int is_attached;
};

4.4 Algorithm Overview

Key Algorithm: Attach-inspect-detach

  1. Find PID of running process.
  2. Attach, inspect stack and variables.
  3. Modify state and detach.

Complexity Analysis:

  • Time: O(1) for inspection tasks.
  • Space: O(1) within debugger.

5. Implementation Guide

5.1 Development Environment Setup

ps aux | head
gdb --version

5.2 Project Structure

project-root/
├── hang.c
└── hang

5.3 The Core Question You’re Answering

“How do I inspect a live process without stopping the service permanently?”

5.4 Concepts You Must Understand First

Stop and research these before coding:

  1. PIDs and process ownership
    • ps, pgrep, permissions
  2. ptrace attachment
    • Why the process stops
    • How detach resumes execution
  3. Signals
    • SIGSTOP on attach
    • SIGINT from Ctrl-C

5.5 Questions to Guide Your Design

  1. What PID should you attach to?
  2. How do you confirm the process is paused?
  3. What is the safest way to resume execution?

5.6 Thinking Exercise

If the process is stuck in a tight loop, how would you identify the exact function and line without restarting it?

5.7 The Interview Questions They’ll Ask

  1. How do you attach to a running process in GDB?
  2. What happens to the target process when you attach?
  3. What is the safest way to exit a live debugging session?

5.8 Hints in Layers

Hint 1: Find PID

  • ps aux | grep hang

Hint 2: Attach

  • gdb -p <PID>

Hint 3: Detach

  • detach then quit

5.9 Books That Will Help

Topic Book Chapter
Process control TLPI Ch. 5, 19
GDB attach “The Art of Debugging with GDB” Ch. 2-3

5.10 Implementation Phases

Phase 1: Foundation (20 minutes)

Goals:

  • Create a long-running process.

Tasks:

  1. Compile hang.c.
  2. Run it in a terminal.

Checkpoint: Process prints continuously.

Phase 2: Core Functionality (20 minutes)

Goals:

  • Attach and inspect.

Tasks:

  1. Find PID and attach.
  2. Run backtrace, info locals.

Checkpoint: You can name the current function and local values.

Phase 3: Polish & Edge Cases (20 minutes)

Goals:

  • Modify state and detach safely.

Tasks:

  1. Change counter with set var.
  2. Detach and observe changed output.

Checkpoint: Process continues with new counter value.

5.11 Key Implementation Decisions

Decision Options Recommendation Rationale
Attach method gdb -p, attach command gdb -p Fast and direct
Detach vs quit detach, quit detach Avoid killing process

6. Testing Strategy

6.1 Test Categories

Category Purpose Examples
Attach Confirm PID attach works gdb -p <PID>
Inspection Verify stack visibility backtrace output
State change Validate modification set var counter = 100

6.2 Critical Test Cases

  1. Attach succeeds without permissions error.
  2. Backtrace shows main in hang.c.
  3. Detach resumes output in terminal.

6.3 Test Data

Looping... counter = N

7. Common Pitfalls & Debugging

7.1 Frequent Mistakes

Pitfall Symptom Solution
Permission error “Operation not permitted” Attach as owner or root
Optimized binary Missing locals Compile with -O0
Quit instead of detach Process terminated Use detach first

7.2 Debugging Strategies

  • If attachment fails, verify PID and user.
  • Use info program to confirm stop state.

7.3 Performance Traps

Attaching can pause a service; keep inspection short in production.


8. Extensions & Challenges

8.1 Beginner Extensions

  • Attach and inspect sleep arguments.

8.2 Intermediate Extensions

  • Set a breakpoint inside the running process.
  • Use call to invoke a function while attached.

8.3 Advanced Extensions

  • Attach to a multi-threaded process and inspect all threads.

9. Real-World Connections

9.1 Industry Applications

  • Incident response: Inspecting hung services without downtime.
  • Performance tuning: Identify hot loops in production.
  • gdb: https://sourceware.org/gdb/
  • strace: Complementary live inspection tool.

9.3 Interview Relevance

  • Demonstrates knowledge of process control and live debugging.

10. Resources

10.1 Essential Reading

  • TLPI - Process management and tracing.
  • GDB Manual - “Attaching” and “Detaching”.

10.2 Video Resources

  • Search: “gdb attach running process”.

10.3 Tools & Documentation

  • ps: man ps
  • GDB: https://sourceware.org/gdb/

11. Self-Assessment Checklist

11.1 Understanding

  • I can explain what happens to a process when GDB attaches.
  • I can list the required permissions.

11.2 Implementation

  • I attached and inspected a live process.
  • I detached without killing it.

11.3 Growth

  • I can apply this workflow to a production service.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Attach to a running process and view a backtrace.

Full Completion:

  • Modify a live variable and detach safely.

Excellence (Going Above & Beyond):

  • Attach to a multi-threaded program and inspect thread states.

This guide was generated from LEARN_GDB_DEEP_DIVE.md. For the complete learning path, see the parent directory README.