LLDB
デバッグツール
LLDB
概要
LLDBは、LLVMプロジェクトの高性能デバッガーです。C、C++、Objective-C、Swiftに対応し、XcodeのデフォルトデバッガーとしてmacOS/iOS開発で標準的に使用されています。
詳細
LLDB(Low-Level Debugger)は、LLVM(Low Level Virtual Machine)プロジェクトの一部として開発された次世代の高性能デバッガーです。2010年にAppleが中心となって開発を開始し、現在ではXcode 5以降のデフォルトデバッガーとして採用されています。LLDBは、C、C++、Objective-C、Swiftなど複数の言語をサポートし、特にSwift言語との統合において優れた機能を提供します。
Apple環境での標準デバッガーとして、Swift言語の普及とともに重要性が増加しており、macOS、iOS、watchOS、tvOSの開発において不可欠なツールとなっています。また、Linux環境でも徐々に採用が広がっており、クロスプラットフォーム対応も進んでいます。
2024年の最新機能では、Swift 6の@DebugDescriptionマクロサポートにより、pコマンドや変数ビューアーの出力をソースコードから直接カスタマイズできるようになりました。LLDBは完全機能のSwiftとClangコンパイラーを内蔵し、式評価器(expression evaluator)を通じて、変数の参照を超えた計算の実行、関数の呼び出し、プログラム状態の変更が可能です。
PythonスクリプトAPIを提供し、繰り返し作業の自動化、深くネストしたオブジェクトの検査、変数の動的操作など高度なデバッグワークフローを実現できます。Swift REPLとの緊密な統合により、インタラクティブな開発とデバッグ体験を提供しています。
メリット・デメリット
メリット
- 高速パフォーマンス: LLVMアーキテクチャによる優秀な実行性能
- Swift完全対応: Swiftデバッグに最適化された専用機能
- Xcode統合: Apple開発環境でのシームレスな統合
- 豊富な式評価: フル機能のコンパイラーによる高度な式評価
- Pythonスクリプティング: 強力な自動化とカスタマイズ機能
- REPL統合: Swift REPLとの緊密な統合
- クロスプラットフォーム: macOS、Linux、FreeBSD、Windowsで動作
- モダンアーキテクチャ: 最新のデバッグ技術と設計パターン
デメリット
- Apple環境依存: 主にApple開発エコシステムに特化
- 学習コスト: GDBとは異なるコマンド体系の習得が必要
- ドキュメント不足: GDBに比べてチュートリアル資料が少ない
- Linux対応の限界: Linux環境での機能制限
- 設定の複雑さ: 高度な機能利用時の設定が煩雑
- メモリ使用量: 高機能な分、メモリ消費が大きい
- コミュニティの小ささ: GDBに比べてコミュニティが小規模
主要リンク
- LLDB公式サイト
- LLDB公式ドキュメント
- LLDB GitHubリポジトリ
- Apple Developer - LLDB
- Swift.org - REPL and Debugger
- LLDB コマンドマップ
書き方の例
LLDBの起動と基本操作
# プログラムをLLDBで起動
lldb ./myprogram
# 実行中のプロセスにアタッチ
lldb -p <process_id>
# Swift REPLモード起動
swift
# または
lldb --repl
# コアダンプ解析
lldb -c core ./myprogram
基本的なLLDBコマンド
# プログラム実行
(lldb) run
(lldb) r
# 引数付きで実行
(lldb) run arg1 arg2
(lldb) settings set target.run-args arg1 arg2
# ブレークポイント設定
(lldb) breakpoint set --name main
(lldb) b main
(lldb) breakpoint set --file main.swift --line 25
(lldb) br s -f main.swift -l 25
# ブレークポイント一覧
(lldb) breakpoint list
(lldb) br list
# ブレークポイント削除
(lldb) breakpoint delete 1
(lldb) br del 1
プログラム実行制御
# ステップイン(関数内に入る)
(lldb) step
(lldb) s
# ステップオーバー(関数をまたぐ)
(lldb) next
(lldb) n
# ステップアウト(関数から出る)
(lldb) finish
(lldb) f
# 実行継続
(lldb) continue
(lldb) c
# 指定行まで実行
(lldb) thread until 30
変数とメモリの検査
# 変数の値表示
(lldb) print variable_name
(lldb) p variable_name
(lldb) po object_name # オブジェクトの説明
# Swift変数の詳細表示
(lldb) v variable_name # 変数の詳細
(lldb) fr var # フレーム内の全変数
# メモリ読み取り
(lldb) memory read 0x12345678
(lldb) mem read -s 1 -f x -c 16 0x12345678
# 変数の値変更
(lldb) expr variable_name = new_value
(lldb) expression -- variable_name = new_value
バックトレースとスタック情報
# バックトレース表示
(lldb) thread backtrace
(lldb) bt
# 全スレッドのバックトレース
(lldb) thread backtrace all
(lldb) bt all
# スタックフレーム選択
(lldb) frame select 0
(lldb) f 0
# フレーム情報表示
(lldb) frame info
(lldb) frame variable # フレーム内変数
Swiftデバッグ専用機能
# Swift式の評価
(lldb) expression let result = someFunction()
(lldb) expr -l swift -- let x = 10
# Swiftオブジェクトのダンプ
(lldb) po myObject
(lldb) expr -O -- myObject
# Swift型情報表示
(lldb) type lookup Swift.String
(lldb) image lookup -t String
# Swift REPL呼び出し
(lldb) repl
高度なデバッグ機能
# 条件付きブレークポイント
(lldb) breakpoint set --name main --condition 'argc > 1'
(lldb) br s -n main -c 'argc > 1'
# ウォッチポイント
(lldb) watchpoint set variable variable_name
(lldb) wa s v variable_name
# 例外ブレークポイント
(lldb) breakpoint set -E swift
(lldb) breakpoint set -E objc
# 関数呼び出し
(lldb) call function_name(args)
(lldb) expression function_name(args)
スレッドとプロセス管理
# スレッド一覧
(lldb) thread list
# スレッド切り替え
(lldb) thread select 2
# プロセス情報
(lldb) process status
(lldb) process continue
(lldb) process kill
# シグナル処理
(lldb) process handle SIGINT -s true -p true
LLDBカスタマイゼーション
# カスタムコマンド定義(~/.lldbinit)
command alias bd breakpoint disable
command alias be breakpoint enable
# Pythonスクリプト
script
import lldb
def hello_command(debugger, command, result, internal_dict):
print("Hello from LLDB!")
lldb.debugger.HandleCommand('command script add -f script.hello_command hello')
script
# 設定変更
(lldb) settings set target.x86-disassembly-flavor intel
(lldb) settings set thread-format "thread #${thread.index}: tid = ${thread.id}{, pc = ${frame.pc}}"
iOS/macOS開発での実用例
# ViewControllerのプロパティ確認
(lldb) po self.view
(lldb) po [self.view recursiveDescription]
# UIの実行時変更
(lldb) expr self.view.backgroundColor = UIColor.red
(lldb) expr (void)[CATransaction flush]
# Core Dataオブジェクトの確認
(lldb) po managedObjectContext.registeredObjects
# Swift Concurrency デバッグ
(lldb) thread list
(lldb) bt
Pythonスクリプトによる自動化
# ~/.lldbinit または独立したPythonファイル
import lldb
def print_all_variables(debugger, command, result, internal_dict):
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
variables = frame.GetVariables(True, True, True, True)
for var in variables:
print(f"{var.name} = {var.value}")
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('command script add -f mymodule.print_all_variables pav')
式評価とREPLの活用
# 複雑な式の評価
(lldb) expr import Foundation
(lldb) expr let url = URL(string: "https://example.com")
(lldb) po url
# 一時関数の定義と実行
(lldb) expr func debugHelper() -> String { return "Debug info" }
(lldb) po debugHelper()
# インラインでのSwiftコード実行
(lldb) expr -l swift --
let formatter = DateFormatter()
formatter.dateStyle = .full
print(formatter.string(from: Date()))