LLDB (Low-Level Debugger) é um depurador de nova geração do projeto LLVM, incluído no Xcode para depuração de aplicativos em iOS, macOS, tvOS e watchOS. Ao contrário do GDB, o LLDB usa uma arquitetura modular com o compilador LLVM, proporcionando alta velocidade e precisão. De acordo com o LLVM Project, o LLDB suporta depuração em C, Objective-C, C++ e Swift com um conjunto completo de recursos: breakpoints, watchpoints, inspeção de memória e execução passo a passo.
Principais pontos
LLDB é um depurador de código aberto construído sobre as bibliotecas do projeto LLVM. Ele substituiu o GDB no Xcode 5 e desde então se tornou a principal ferramenta de depuração para todo o ecossistema Apple. Ao contrário do GDB monolítico, o LLDB é implementado como um conjunto de bibliotecas interativas: cada função — desde a análise de expressões até o gerenciamento de memória — está em um módulo separado, simplificando a manutenção e a extensão.
As principais capacidades do LLDB incluem: definir breakpoints de qualquer tipo, watchpoints para rastrear alterações de variáveis, inspeção de memória e registradores, execução passo a passo, avaliação de expressões arbitrárias no contexto de um programa interrompido e execução de scripts Python para automação. De acordo com o repositório LLVM, o LLDB suporta mais de 200 comandos de depuração e é compatível com os formatos DWARF e Mach-O — os principais formatos de informação de depuração no ecossistema Apple.
Uma vantagem importante do LLDB é sua profunda integração com o Clang. Ao usar o mesmo compilador para analisar e compilar código fonte, o LLDB pode avaliar expressões C++ e Objective-C com uma precisão não disponível no GDB. Para depuração Swift, o LLDB usa um módulo separado do Swift Language Runtime que entende a semântica da linguagem: tipos opcionais, protocolos, genéricos e gerenciamento de memória via ARC.
A primeira versão do LLDB apareceu em 2010 como parte do LLVM 2.8. Em 2013, ele já havia substituído completamente o GDB no Xcode. Em 2019, com o lançamento do Xcode 11, o LLDB ganhou suporte para Swift Error Breakpoints e um analisador de expressões melhorado para Swift. De acordo com a Apple, desde o iOS 14, toda a pilha de depuração para o simulador também funciona através do LLDB, confirmando seu status como a principal ferramenta de depuração da plataforma.
A arquitetura do LLDB é construída com base no princípio de microsserviços: cada subsistema existe como uma biblioteca separada (dylib), conectada a outras através de uma API comum. Isso o distingue do GDB, onde todas as funções são combinadas em um único binário. A estrutura modular permite usar os componentes do LLDB de forma independente — por exemplo, o analisador de expressões pode ser incorporado a um IDE sem conectar o depurador completo.
| Componente do LLDB | Finalidade | Biblioteca |
|---|---|---|
| Core | Gerenciamento do processo de depuração, eventos, estados de threads | liblldbCore.dylib |
| Expression Parser | Análise e execução de expressões (C/C++/ObjC/Swift) | liblldbExpression.dylib |
| Symbol File | Leitura de DWARF, Mach-O, dSYM — trabalho com informações de depuração | liblldbSymbol.dylib |
| Target Control | Controle de execução: iniciar, parar, passos | liblldbTarget.dylib |
| Interpreter | Linha de comando e modo REPL | liblldbInterpreter.dylib |
dSYM são arquivos de informação de depuração que o Xcode gera durante a compilação. O LLDB os utiliza para mapear o código de máquina para o código fonte: sem dSYM, o depurador mostra apenas endereços de memória em vez de nomes de funções e linhas de código. Para aplicativos da App Store, os arquivos dSYM são enviados separadamente para o servidor da Apple e usados para simbolizar logs de falhas recebidos dos usuários através do 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
Os comandos do LLDB são divididos em várias categorias: controle de execução, gerenciamento de breakpoints, inspeção de dados e manipulação de memória. Ao contrário da interface gráfica do Xcode, o console do LLDB fornece controle total sobre a depuração e permite operações não disponíveis através da interface gráfica — por exemplo, alterar o valor de uma variável em tempo real ou editar breakpoints em massa.
Continue, Step Over, Step Into, Step Out — a base do ciclo de depuração. continue retoma a execução até o próximo breakpoint. step over executa a linha atual por completo. step into entra dentro do método chamado. step out completa a função atual e retorna o controle ao código chamador. Adicionalmente, existe step with type filter — passo até o tipo de dados especificado.
(lldb) thread backtrace # Mostrar a pilha de chamadas
* 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 # Mostrar variáveis locais
(Int) userId = 42
(String) endpoint = "https://api.example.com/user/42"
(lldb) thread step-over # Step Over
(lldb) thread step-in # Step Into
O LLDB fornece comandos para visualizar dados em qualquer formato: memory read, frame variable, target variable. A sintaxe especial po (print object) chama debugDescription em objetos Objective-C e description em tipos Swift. Formatadores personalizados são definidos via type summary add — útil para depurar estruturas complexas como CGRect ou IndexPath.
(lldb) po userProfile # Exibir descrição do objeto
<UserProfile: 0x600000c4b80>
- name: "John"
- age: 30
- email: "john@example.com"
(lldb) expression userProfile.age = 31 # Alterar o valor
(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
A avaliação de expressões no LLDB é um dos recursos mais poderosos, ausente no GDB na época de seu domínio. O LLDB pode executar código arbitrário em C, Objective-C, C++ e Swift no contexto de um programa interrompido, incluindo chamada de métodos, criação de objetos e modificação de estado. Isso permite testar hipóteses sem reiniciar o aplicativo e recompilar.
O comando expression compila e executa uma expressão em tempo de execução do processo depurado. A flag -O (object description) aciona po. Para expressões multilinha, use expression -l Swift --. O LLDB compila código em tempo real através do Clang ou Swift Compiler, integra o resultado no contexto atual e retorna o valor. De acordo com a Apple, uma expressão compila em 10–50 ms dependendo da complexidade.
(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
O LLDB permite não apenas ler, mas também modificar o estado de objetos e variáveis durante a depuração. Isso é crítico para testar casos extremos: pode-se definir uma variável como nil, alterar a cor de um elemento de UI ou substituir uma resposta do servidor diretamente no depurador, sem recompilar e reiniciar. Esta técnica é amplamente utilizada no desenvolvimento de jogos e aplicativos com fluxos longos, onde reiniciar leva muito tempo.
(lldb) expr self.label.text = @"Updated"
(lldb) expr -l Swift -- (self as! UIViewController).view.backgroundColor = .red
(lldb) expr let $snapshot = self.view.debugQuickLookObject()
A API Python no LLDB permite escrever scripts para automatizar a depuração. Através do Python, é possível criar comandos personalizados, manipular eventos de breakpoint, gerar relatórios e até mesmo sobrescrever o comportamento do depurador. O interpretador Python 3 embutido é executado diretamente dentro do LLDB, com acesso à API completa de depuração através do módulo lldb.
Um novo comando do LLDB pode ser registrado através do decorador @classmethod em um script Python. Após importar o script, o comando fica disponível como um comando nativo. Por exemplo, o comando printvars pode exibir todas as variáveis do quadro atual com seus tipos e valores, formatados para um projeto específico. A automação reduz o tempo de operações típicas de depuração em 60–80%, de acordo com uma pesquisa de desenvolvedores iOS no 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}")
Através da API Python, é possível vincular um script à ativação de um breakpoint. Defina um breakpoint, execute breakpoint command add e especifique uma função Python. Isso permite registrar automaticamente o estado, enviar dados para análises ou verificar invariantes sem intervenção manual. De acordo com a LLVM, esta abordagem é usada na infraestrutura da Apple para coletar métricas de desempenho durante o desenvolvimento.
(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) é um modo interativo do LLDB, invocado com o comando lldb --repl ou através do console de depuração do Xcode. No REPL, é possível executar código Swift ou C como em um playground, com feedback instantâneo. O LLDB compila cada linha, executa e mostra o resultado — conveniente para experimentar com APIs, prototipar algoritmos e aprender novos recursos da linguagem sem criar um projeto.
(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
O modo REPL também suporta carregamento de módulos e frameworks via import. Por exemplo, import UIKit no REPL carrega toda a biblioteca UIKit, permitindo criar elementos de UI, verificar constraints e testar animações. Esta é uma capacidade única para desenvolvedores iOS, indisponível no GDB — depuração e prototipação no mesmo ambiente.
Graças à integração com o compilador Swift, o LLDB REPL é usado nos cursos da Apple para ensinar Swift. Os alunos podem executar código linha por linha, ver tipos e resultados sem se distrair com a configuração do projeto. Esta abordagem segue a metodologia de Aprendizagem Ativa, onde o feedback interativo acelera a compreensão do material em 40%, de acordo com pesquisas em Educação em Ciência da Computação.
Perguntas frequentes
LLDB é construído sobre uma arquitetura LLVM modular, o que lhe dá vantagem em velocidade de avaliação de expressões e suporte a linguagens modernas (Swift). GDB é um depurador monolítico que não suporta Swift e tem capacidades limitadas de scripting.
Instale o Command Line Tools via xcode-select --install, depois execute lldb --repl no terminal. O LLDB está disponível em /Library/Developer/CommandLineTools/usr/bin/.
Sim, via lldb --attach-pid PID ou process attach --name AppName. O LLDB pausará o processo, após o qual todos os comandos padrão de depuração estão disponíveis sem reiniciar o aplicativo.
Os arquivos de informação de depuração dSYM estão faltando. Verifique as configurações de Build Settings: Generate Debug Symbols deve ser YES, e Debug Information Format deve ser DWARF with dSYM File.
O LLDB salva automaticamente o histórico em ~/.lldb/lldb-history. Para exportar, use session save filename.txt — o comando salva todos os comandos executados da sessão atual em um arquivo de texto.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também