Section 3/162 menit

3. Teori: Cara Kerja LLDB

3. Teori: Cara Kerja LLDB

Arsitektur: Debugger vs Debugee

LLDB beroperasi sebagai proses terpisah yang berkomunikasi dengan aplikasi (debugee) melalui system calls khusus. Di macOS/iOS, mekanisme ini menggunakan ptrace system call dan Mach exception ports.

Ketika LLDB "melampirkan" ke proses:

  1. LLDB menginjeksi dirinya ke dalam proses target
  2. Mengambil kontrol semua threads
  3. Memasang exception handler untuk menangkap crash, signals, dan breakpoints
  4. Memberikan kontrol ke developer melalui LLDB prompt

Cara Kerja Breakpoint

Ketika Anda menetapkan breakpoint di baris tertentu, LLDB:

  1. Menemukan alamat memori yang berkorespondensi dengan baris tersebut (menggunakan debug symbols / DWARF)
  2. Mengganti instruction pertama di alamat itu dengan instruksi INT 3 (x86) atau BRK (ARM) — interrupt instruction
  3. Ketika CPU mengeksekusi interrupt instruction, kontrol berpindah ke LLDB
  4. LLDB mengembalikan instruction asli sebelum melanjutkan eksekusi

Itulah mengapa breakpoint bekerja tanpa mengubah source code — hanya instruction di memori yang dimodifikasi sementara.

DWARF Debug Symbols

LLDB mengetahui nama variabel, tipe, dan mapping baris kode → alamat memori melalui DWARF (Debugging With Attributed Record Formats) yang tersimpan di .dSYM bundle. Ketika build dengan konfigurasi Debug, compiler menyertakan DWARF; ketika Release tanpa DWARF_DSYM_FILE_SHOULD_ACCOMPANY_PRODUCT = YES, simbol tidak ada dan debugging menjadi sangat terbatas.

Swift-Specific: Mangling dan Reflection

LLDB untuk Swift memiliki pengetahuan khusus tentang Swift type system:

  • Name mangling: LLDB bisa demangle nama Swift yang di-mangle (seperti _$s6MyApp5UserC4nameSSvg) kembali ke nama yang readable
  • Reflection: LLDB menggunakan Swift runtime reflection untuk menampilkan properti struct, class, dan enum
  • Existential container: LLDB bisa "membuka" existential types untuk menampilkan concrete type di dalamnya