Project 5: LLDB Python Scripting

Write a Python module that adds a custom LLDB command.

Quick Reference

Attribute Value
Difficulty Advanced
Time Estimate ~1 week
Language Python (LLDB SB API)
Prerequisites Projects 1-4, Python basics
Key Topics SB API, command scripts, automation

1. Learning Objectives

By completing this project, you will:

  1. Write and import a Python module into LLDB.
  2. Access the target, process, thread, and frame objects.
  3. Register a custom LLDB command.
  4. Print a structured summary of the current frame.

2. Theoretical Foundation

2.1 Core Concepts

  • SB API: LLDB’s object-oriented interface for scripts.
  • Custom command: A Python function mapped to a command name.
  • Initialization: __lldb_init_module auto-load hook.

2.2 Why This Matters

Automation turns 10 manual commands into 1. It is the difference between a slow investigation and a repeatable workflow.

2.3 Common Misconceptions

  • “Scripts are only for huge projects.” (Even a tiny command saves time.)
  • “The SB API is too complex.” (You only need a handful of objects to start.)

3. Project Specification

3.1 What You Will Build

A Python module (myscripts.py) that adds a frame_summary command to LLDB. It prints the current function, source location, and local variables.

3.2 Functional Requirements

  1. The module imports without errors.
  2. frame_summary prints function name + file:line.
  3. The command lists local variables with values.
  4. The command handles invalid frames gracefully.

3.3 Non-Functional Requirements

  • Robustness: Handle missing targets or frames.
  • Readability: Output should be clean and consistent.

3.4 Example Usage / Output

(lldb) command script import myscripts.py
(lldb) frame_summary

3.5 Real World Outcome

$ lldb ./target
(lldb) command script import myscripts.py
(lldb) b main
(lldb) run
(lldb) frame_summary
Function: main
Location: /path/to/target.c:8
Locals:
  - i = 0

4. Solution Architecture

4.1 High-Level Design

LLDB -> Python Script -> SB API -> Custom Command Output

4.2 Key Components

Component Responsibility Key Decisions
Python module Implement command Clean error handling
SB API objects Access state Target -> Process -> Thread -> Frame
LLDB command User entry point frame_summary

5. Implementation Guide

5.1 Development Environment Setup

# Ensure LLDB has Python support
lldb

5.2 Project Structure

project-root/
|-- myscripts.py
`-- notes.md

5.3 The Core Question You’re Answering

“How can I turn repetitive inspection steps into a single LLDB command?”

5.4 Concepts You Must Understand First

  1. SB API object model
    • Book: Building a Debugger - Ch. 1-2
  2. Python functions and modules
    • Book: Fluent Python - Ch. 7-9
  3. Debugger scripting
    • Book: The Art of Debugging with GDB, DDD, and Eclipse - Ch. 7

5.5 Questions to Guide Your Design

  1. Which SB objects do you need to reach the current frame?
  2. What should you do if no target is selected?
  3. What output format is easiest to scan under pressure?

5.6 Thinking Exercise

List the three LLDB commands you type most often. Could you replace them with one command?

5.7 The Interview Questions They’ll Ask

  1. What does SBDebugger represent?
  2. How do you register a Python function as a command?
  3. What is __lldb_init_module used for?
  4. How do you access locals in a frame?

5.8 Hints in Layers

Hint 1: Use the standard function signature

def mycmd(debugger, command, result, internal_dict):
    pass

Hint 2: Guard against invalid state

if not debugger.GetSelectedTarget():
    result.SetError("Invalid target")

Hint 3: Register the command

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f mymod.mycmd mycmd')

5.9 Books That Will Help

Topic Book Chapter
Debugger internals Building a Debugger Ch. 1-2
Python scripting Fluent Python Ch. 7-9
Debugging mindset The Art of Debugging with GDB, DDD, and Eclipse Ch. 7

5.10 Implementation Phases

Phase 1: Minimal Command (1-2 hours)

  • Print the current function name only.

Phase 2: Rich Output (2-4 hours)

  • Add file:line and local variables.

Phase 3: Polish (1-2 hours)

  • Handle errors and improve output formatting.

5.11 Key Implementation Decisions

Decision Options Recommendation Rationale
Output format Plain vs structured Structured Faster to read

6. Testing Strategy

6.1 Test Categories

Category Purpose Examples
Import tests Ensure module loads No errors on import
Command tests Validate output Function + line shown

6.2 Critical Test Cases

  1. frame_summary works when stopped in main.
  2. The command handles missing targets gracefully.

7. Common Pitfalls & Debugging

Pitfall Symptom Solution
Module not found Import fails Use correct path or current directory
Wrong function signature Command errors Use LLDB signature

8. Extensions & Challenges

  • Add register output to your summary.
  • Add an option flag for verbose output.

9. Real-World Connections

  • Teams often maintain custom LLDB command sets for their codebases.
  • Scripted debugging is common in large systems and kernel work.

10. Resources

  • LLDB Python Reference: https://lldb.llvm.org/use/python-reference.html
  • LLDB Command Reference: https://lldb.llvm.org/use/commandref.html

11. Self-Assessment Checklist

  • I can load a Python module in LLDB.
  • I can access the current frame via the SB API.
  • I can register a custom command.

12. Submission / Completion Criteria

Minimum Viable Completion:

  • Command prints the current function name.

Full Completion:

  • Command prints file, line, and local variables.

Excellence (Going Above & Beyond):

  • Add a --verbose flag and handle it in your command.

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