LLDB (Low-Level Debugger) — дебагер нове генерације из LLVM пројекта, који је део Xcode-а за дебаговање апликација за iOS, macOS, tvOS и watchOS. За разлику од GDB-а, LLDB користи модуларну архитектуру са LLVM компајлером, што обезбеђује велику брзину и прецизност. Према подацима LLVM Project, LLDB подржава дебаговање на језицима C, Objective-C, C++ и Swift са комплетним скупом функција: breakpoints, watchpoints, инспекција меморије и извођење корак по корак.
Главно
LLDB — је дебагер отвореног кода, изграђен на библиотекама LLVM пројекта. Заменио је GDB у Xcode 5 и од тада је главни алат за дебаговање за цео Apple екосистем. За разлику од монолитног GDB-а, LLDB је имплементиран као скуп библиотека које међусобно сарађују: свака функција — од парсинга израза до рада са меморијом — издвојена је у посебан модул, што поједностављује одржавање и проширење.
Основне могућности LLDB-а укључују: постављање breakpoints било ког типа, watchpoints за праћење промена променљивих, инспекцију меморије и регистара, извођење корак по корак, израчунавање произвољних израза у контексту заустављеног програма и извршавање Python скрипти за аутоматизацију. Према подацима LLVM репозиторијума, LLDB подржава преко 200 команди за дебаговање и компатибилан је са DWARF и Mach-O форматима — главним форматима информација за дебаговање у Apple екосистему.
Важна предност LLDB-а је дубока интеграција са Clang-ом. Захваљујући коришћењу истог компајлера за парсинг и компилацију изворног кода, LLDB може да израчунава C++ и Objective-C изразе са прецизношћу недоступном GDB-у. За Swift дебаговање, LLDB користи посебан модул Swift Language Runtime, који разуме семантику језика: опционалне типове, протоколе, генеричке типове и управљање меморијом кроз ARC.
Прва верзија LLDB-а појавила се 2010. године као део LLVM 2.8. До 2013. године потпуно је заменио GDB у Xcode-у. Године 2019. са издавањем Xcode 11, LLDB је добио подршку за Swift Error Breakpoints и побољшани парсер израза за Swift. Према подацима Apple-а, од iOS 14, цео стек за дебаговање за симулатор такође ради преко LLDB-а, што потврђује његов статус главног алата за дебаговање платформе.
Архитектура LLDB-а је изграђена по принципу микросервиса: сваки подсистем постоји као засебна библиотека (dylib), повезана са другима кроз заједнички API. То га разликује од GDB-а, где су све функције обједињене у један бинарни фајл. Модуларна структура омогућава независно коришћење компоненти LLDB-а — на пример, парсер израза се може уградити у IDE без повезивања пуног дебагера.
| Компонента LLDB-а | Намена | Библиотека |
|---|---|---|
| Core | Управљање процесом дебаговања, догађаји, стања нити | liblldbCore.dylib |
| Expression Parser | Парсинг и извршавање израза (C/C++/ObjC/Swift) | liblldbExpression.dylib |
| Symbol File | Читање DWARF, Mach-O, dSYM — рад са информацијама за дебаговање | liblldbSymbol.dylib |
| Target Control | Управљање извршавањем: покретање, заустављање, кораци | liblldbTarget.dylib |
| Interpreter | Командна линија и REPL режим | liblldbInterpreter.dylib |
dSYM — су фајлови информација за дебаговање које Xcode генерише при компилацији. LLDB их користи за повезивање машинског кода са изворним кодом: без dSYM дебагер показује само адресе у меморији уместо имена функција и линија кода. За апликације из App Store-а, dSYM фајлови се посебно учитавају на Apple сервер и користе за символизацију crash-logova добијених од корисника путем CrashReporter-а.
(lldb) target create MyApp.app
(lldb) image list MyApp
MyApp - "/path/to/MyApp.app/MyApp" (arm64)
(lldb) image lookup -n fetchUserData
Address: MyApp[0x1000a3b40] (MyApp.__TEXT.__text + 12352)
Summary: `ViewController.fetchUserData()` at ViewController.swift:42
Команде LLDB-а се деле у неколико категорија: управљање извршавањем, рад са breakpoints, инспекција података и манипулација меморијом. За разлику од Xcode GUI-ја, конзола LLDB-а даје потпуну контролу над дебаговањем и омогућава извођење операција недоступних кроз графички интерфејс — на пример, промену вредности променљиве у лету или масовно уређивање breakpoints.
Continue, Step Over, Step Into, Step Out — основа циклуса дебаговања. continue наставља извршавање до следећег breakpoint-а. step over извршава тренутну линију у целини. step into улази у позвани метод. step out завршава тренутну функцију и враћа контролу позивајућем коду. Додатно постоји step with type filter — корак до наведеног типа података.
(lldb) thread backtrace # Показать стек вызовов
* thread #1, queue = 'com.apple.main-thread'
frame #0: 0x1000a3b40 ViewController`fetchUserData()
frame #1: 0x1000a2000 ViewController`viewDidLoad()
frame #2: 0x1a2b345 UIKit`UIViewController.loadView()
(lldb) frame variable # Показать локальные переменные
(Int) userId = 42
(String) endpoint = "https://api.example.com/user/42"
(lldb) thread step-over # Step Over
(lldb) thread step-in # Step Into
LLDB пружа команде за преглед података у било ком формату: memory read, frame variable, target variable. Посебна синтакса po (print object) позива debugDescription код Objective-C објеката и description код Swift типова. Прилагођени форматизери се постављају путем type summary add — корисно за дебаговање сложених структура, као што су CGRect или IndexPath.
(lldb) po userProfile # Вывод описания объекта
<UserProfile: 0x600000c4b80>
- name: "John"
- age: 30
- email: "john@example.com"
(lldb) expression userProfile.age = 31 # Изменить значение
(Int) $R0 = 31
(lldb) memory read 0x600000c4b80 0x600000c4bc0
0x600000c4b80: 6a 6f 68 6e 00 00 00 00 1e 00 00 00 00 00 00 00
Израчунавање израза у LLDB-у је једна од најмоћнијих функција, која је недостајала у GDB-у у време његове доминације. LLDB може да извршава произвољни код на C, Objective-C, C++ и Swift у контексту заустављеног програма, укључујући позивање метода, креирање објеката и модификацију стања. То омогућава тестирање хипотеза без поновног покретања апликације и рекомпилације.
Команда expression компајлира и извршава израз у рантајму процеса који се дебагује. Застава -O (object description) позива po. За вишлинијске изразе користите expression -l Swift --. LLDB компајлира код у лету кроз Clang или Swift Compiler, интегрише резултат у тренутни контекст и враћа вредност. Према подацима Apple-а, израз се компајлира за 10–50 ms у зависности од сложености.
(lldb) expr -l Swift -- UIAlertController(title: "Test", message: nil,
preferredStyle: .alert)
(lldb) expr let $arr = [1, 2, 3].map { $0 * 2 }
(lldb) po $arr
▿ 3 elements
- 0 : 2
- 1 : 4
- 2 : 6
LLDB омогућава не само читање, већ и мењање стања објеката и променљивих током дебаговања. То је кључно за тестирање граничних случајева: могуће је поставити вредност променљиве на nil, променити боју UI елемента или заменити одговор сервера директно у дебагеру, без рекомпилације и поновног покретања. Техника се широко примењује у развоју игара и апликација са дугим токовима, где поновно покретање траје дуго.
(lldb) expr self.label.text = @"Updated"
(lldb) expr -l Swift -- (self as! UIViewController).view.backgroundColor = .red
(lldb) expr let $snapshot = self.view.debugQuickLookObject()
Python API LLDB-а омогућава писање скрипти за аутоматизацију дебаговања. Кроз Python се могу креирати прилагођене команде, обрађивати догађаји breakpoint-а, генерисати извештаји, па чак и мењати понашање дебагера. Уграђени Python 3 интерпретатор се покреће директно унутар LLDB-а, са приступом потпуном API-ју за дебаговање кроз модул lldb.
Регистровати нову LLDB команду може се кроз декоратор @classmethod у Python скрипти. Након увоза скрипте, команда постаје доступна као уграђена. На пример, команда printvars може да прикаже све променљиве тренутног оквира са њиховим типовима и вредностима, форматиране за одређени пројекат. Аутоматизација смањује време типичних операција дебаговања за 60–80%, према анкети iOS програмера на Stack Overflow-у.
import lldb
class PrintVarsCommand:
@classmethod
def register_class(cls, debugger, _):
handler = PrintVarsCommand()
debugger.HandleCommand('command script add -c \
print_vars.PrintVarsCommand printvars')
def __call__(self, debugger, command, exe_ctx, result):
frame = exe_ctx.frame
for var in frame.variables:
result.AppendMessage(f"{var.name}: {var.type} = {var.value}")
Кроз Python API може се прикачити скрипта на активирање breakpoint-а. Поставите breakpoint, затим извршите breakpoint command add и наведите Python функцију. То омогућава аутоматско логирање стања, слање података у аналитику или проверу инваријанти без ручне интервенције. Према подацима LLVM-а, овај приступ се користи у Apple инфраструктури за прикупљање метрика перформанси у фази развоја.
(lldb) breakpoint set -f Model.swift -l 100
(lldb) breakpoint command add 1 -s python -o "frame = exe_ctx.frame;
print([var.name for var in frame.variables])"
REPL (Read-Eval-Print Loop) — интерактивни режим LLDB-а, који се позива командом lldb --repl или кроз Xcode Debug Console. У REPL-у се може извршавати код на Swift или C као у playground-у, са тренутном повратном информацијом. LLDB компајлира сваку линију, извршава је и приказује резултат — то је погодно за експериментисање са API-јем, прототиповање алгоритама и учење нових могућности језика без креирања пројекта.
(lldb) --repl
1> let numbers = [1, 2, 3, 4, 5]
2> numbers.filter { $0 % 2 == 0 }
$R0: [Int] = 2 values {
[0] = 2
[1] = 4
}
3> let result = numbers.reduce(0, +)
$R1: Int = 15
REPL режим такође подржава учитавање модула и фрејмворка кроз import. На пример, import UIKit у REPL-у учитава целу UIKit библиотеку, и могуће је креирати UI елементе, проверавати constraint-е и тестирати анимације. То је јединствена могућност за iOS програмере, недоступна у GDB-у — дебаговање и прототиповање у истом окружењу.
Захваљујући интеграцији са Swift Compiler-ом, LLDB REPL се користи на Apple курсевима за учење Swift-а. Студенти могу да извршавају код линију по линију, виде типове и резултате, без ометања подешавањем пројекта. Овај приступ је у складу са методом Active Learning, где интерактивна повратна информација убрзава усвајање градива за 40% према истраживањима у области Computer Science Education.
Често постављана питања
LLDB је изграђен на модуларној LLVM архитектури, што му даје предност у брзини рада са изразима и подршци савременим језицима (Swift). GDB — монолитни дебагер који не подржава Swift и има ограничене могућности скриптовања.
Инсталирајте Command Line Tools путем xcode-select --install, затим извршите lldb --repl у терминалу. LLDB је доступан у /Library/Developer/CommandLineTools/usr/bin/.
Да, путем lldb --attach-pid PID или process attach --name AppName. LLDB ће зауставити процес, након чега су доступне све стандардне команде дебаговања без поновног покретања апликације.
Недостају dSYM фајлови информација за дебаговање. Проверите подешавања Build Settings: Generate Debug Symbols мора бити YES, а Debug Information Format — DWARF with dSYM File.
LLDB аутоматски чува историју у ~/.lldb/lldb-history. За извоз користите session save filename.txt — команда чува све извршене команде текуће сесије у текстуални фајл.
Завршни преглед
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође