Project 3: The Hang - Attaching to a Running Process

Attach LLDB to a live process, inspect threads, and detach safely.

Quick Reference

Attribute Value
Difficulty Intermediate
Time Estimate 2-3 hours
Language C (LLDB commands)
Prerequisites Projects 1-2, process basics
Key Topics Attach/detach, thread backtraces

1. Learning Objectives

By completing this project, you will:

  1. Attach LLDB to a running process by PID.
  2. Inspect thread states and backtraces.
  3. Identify where a program is blocked.
  4. Detach without killing the process.

2. Theoretical Foundation

2.1 Core Concepts

  • Attach: Connect LLDB to a running process.
  • SIGSTOP: A signal used to pause a process.
  • Thread backtrace: The stack for each thread.

2.2 Why This Matters

In production, you cannot restart or recompile a hung service. Attach-and-inspect is your primary tool.

2.3 Common Misconceptions

  • “Attach kills the process.” (It only pauses it temporarily.)
  • “Only one thread matters.” (Hangs often involve multiple threads.)

3. Project Specification

3.1 What You Will Build

A small program that loops forever. You will attach LLDB to it from a second terminal and inspect its state.

3.2 Functional Requirements

  1. Attach by PID and verify the process stops.
  2. Print thread backtraces and identify the blocked thread.
  3. Modify a variable at runtime.
  4. Detach cleanly.

3.3 Non-Functional Requirements

  • Safety: Detach without killing the process.
  • Clarity: Notes clearly identify where the program is blocked.

3.4 Example Usage / Output

(lldb) process attach --pid 12345
(lldb) thread backtrace all
(lldb) detach

3.5 Real World Outcome

$ clang -g -O0 -o hang hang.c
$ ./hang
$ pgrep hang
12345
$ lldb
(lldb) process attach --pid 12345
Process 12345 stopped
* thread #1, stop reason = signal SIGSTOP
    frame #0: 0x00007fff2031d7d8 libsystem_c.dylib`nanosleep
(lldb) thread backtrace all
(lldb) frame select 1
(lldb) frame variable counter
(int) counter = 10
(lldb) expr counter = 100
(int) $0 = 100
(lldb) detach
Process 12345 detached

4. Solution Architecture

4.1 High-Level Design

Live Process -> Attach -> Inspect Threads -> Modify State -> Detach

4.2 Key Components

Component Responsibility Key Decisions
Running process Provide live state Use deterministic loop
LLDB attach Pause and inspect Attach by PID
Thread analysis Find hang point thread backtrace all

5. Implementation Guide

5.1 Development Environment Setup

clang -g -O0 -o hang hang.c
./hang

5.2 Project Structure

project-root/
|-- hang.c
`-- notes.md

5.3 The Core Question You’re Answering

“How do I pause a live process, inspect its threads, and leave it running safely?”

5.4 Concepts You Must Understand First

  1. Process and thread states
    • Book: Operating Systems: Three Easy Pieces - Ch. 4-5, 26
  2. Attach/detach workflow
    • Book: The Art of Debugging with GDB, DDD, and Eclipse - Ch. 2-3
  3. Stack frames
    • Book: Computer Systems: A Programmer’s Perspective - Ch. 3

5.5 Questions to Guide Your Design

  1. How do you identify which thread is blocked?
  2. How do you tell if you are inside your code vs a library call?
  3. How do you modify a variable safely at runtime?

5.6 Thinking Exercise

List three reasons a program might hang and describe the backtrace you would expect for each.

5.7 The Interview Questions They’ll Ask

  1. What is the difference between attaching and launching?
  2. How do you detect a deadlock with a debugger?
  3. Why is detaching important for production systems?
  4. What does SIGSTOP mean in this context?

5.8 Hints in Layers

Hint 1: List threads first

(lldb) thread list

Hint 2: Dump all backtraces

(lldb) thread backtrace all

Hint 3: Change a variable live

(lldb) expr counter = 100

5.9 Books That Will Help

Topic Book Chapter
Processes Operating Systems: Three Easy Pieces Ch. 4-5
Threads Operating Systems: Three Easy Pieces Ch. 26
Debugging workflow The Art of Debugging with GDB, DDD, and Eclipse Ch. 2-3

5.10 Implementation Phases

Phase 1: Setup (30 min)

  • Build and run the hang program.

Phase 2: Attach + Inspect (60 min)

  • Attach to the PID and inspect thread backtraces.

Phase 3: Modify + Detach (30 min)

  • Change a variable, then detach cleanly.

5.11 Key Implementation Decisions

Decision Options Recommendation Rationale
Attach method PID vs name PID Deterministic

6. Testing Strategy

6.1 Test Categories

Category Purpose Examples
Attach tests Verify attach works SIGSTOP in LLDB
Thread inspection Ensure visibility Backtraces available

6.2 Critical Test Cases

  1. LLDB attaches and stops process.
  2. Backtrace shows the loop in your code.

7. Common Pitfalls & Debugging

Pitfall Symptom Solution
Permission denied Attach fails Use same user or sudo
No symbols ?? frames Rebuild with -g

8. Extensions & Challenges

  • Add a mutex and create a real deadlock to inspect.
  • Attach to a long-running system service (non-destructive).

9. Real-World Connections

  • Incident response often starts with attaching to a hung service.
  • Thread backtraces are the fastest way to find lock contention.

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 attach and detach without killing a process.
  • I can identify where a program is blocked.
  • I can change a variable at runtime.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Attach to a running process.
  • Produce a thread backtrace.

Full Completion:

  • Modify a variable and detach safely.

Excellence (Going Above & Beyond):

  • Debug a real deadlock you created.

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