Belajar LLVM - Debug Information & Metadata
Series/Belajar LLVM/Episode 14
Episode 14 of 28

Belajar LLVM - Debug Information & Metadata

Membangun debug information untuk mini language menggunakan DIBuilder: generate DWARF metadata agar bisa didebug di gdb/lldb, memahami metadata nodes vs named metadata, TBAA untuk alias analysis, dan step-through mini language di lldb.

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 13 kita mengintegrasikan optimasi dan menangani variabel mutable dengan alloca-bump, pada episode ini kita menambahkan aspek yang sering dilewatkan tetapi sangat penting untuk production: debug information.

Tanpa debug info, kalian tidak bisa mendebug kode yang dihasilkan LLVM di gdb/lldb. Debug info dalam LLVM direpresentasikan sebagai metadata — data tambahan yang melekat pada IR tanpa mempengaruhi codegen. Untuk mini language kita, debug info memungkinkan step-through baris per baris di debugger.

DIBuilder: Generate DWARF Metadata

LLVM menyediakan DIBuilder untuk membuat debug info dalam format DWARF:

Setup DIBuilder
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
 
// Di setup module
DIBuilder *DBuilder = new DIBuilder(*M);
 
// Buat file debug
DIFile *File = DBuilder->createFile("repl.kaleidoscope", ".");
 
// Buat compile unit
DICompileUnit *CU = DBuilder->createCompileUnit(
    dwarf::DW_LANG_C, File, "Kaleidoscope REPL", false, "", 0);
 
// Buat fungsi debug info
DISubroutineType *FuncType = DBuilder->createSubroutineType(
    DBuilder->getOrCreateTypeArray({DBuilder->createBasicType(
        "double", 64, dwarf::DW_ATE_float)}));
 
DISubprogram *SP = DBuilder->createFunction(
    File, "fib", "fib", File, 0, FuncType,
    0, llvm::DISPFlags::SPFlagDefinition, 0);

Attach ke Fungsi

Attach debug info ke function
Function *F = ...;
F->setSubprogram(SP);
 
// Set debug location untuk instruksi
Builder->SetCurrentDebugLocation(
    llvm::DebugLoc::get(1, 0, SP));
 
// Buat variabel debug
auto *DIVar = DBuilder->createAutoVariable(
    SP, "x", File, 1, DBuilder->createBasicType("double", 64, dwarf::DW_ATE_float));
DBuilder->insertDbgValueIntrinsic(
    &F->arg_begin()[0], llvm::_DBG_VALUE_LIST{}, DIVar,
    DBuilder->createExpression(nullptr),
    llvm::DebugLoc::get(1, 0, SP),
    Builder->GetInsertBlock());

DIBuilder akan menghasilkan metadata DWARF yang dikenali oleh gdb/lldb.

Metadata Nodes vs Named Metadata

Metadata Nodes

Metadata nodes adalah data terstruktur yang melekat pada instruksi:

Metadata pada instruksi
%sum = add i32 %a, !tbaa !5

Named Metadata

Named metadata adalah metadata module-level dengan nama:

Named metadata
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!1, !2}
!0 = distinct !DICompileUnit(...)
!1 = !{i32 7, !"Dwarf Version", i32 5}

TBAA (Type-Based Alias Analysis)

TBAA membantu optimizer menentukan apakah dua pointer bisa menunjuk ke memory yang sama:

TBAA metadata
; Struktur TBAA: type node → parent node
!tbaa = !{!1, !2, !6}
!1 = !{!"Simple C/C++ TBAA"}
!2 = !{!"omnipotent char", !1, i64 0}
!6 = !{!"int", !2, i64 0}
 
; Penggunaan
%val = load i32, ptr %p, !tbaa !6

Note

TBAA memberitahu optimizer: "load ini dari tipe int; ia tidak bisa tumpang tindih dengan pointer ke float." Ini memungkinkan optimizer menghapus load redundan dan reorder instruksi dengan aman. Tanpa TBAA, optimizer harus asumsikan semua pointer bisa tumpang tindih (alias).

Praktik: Step-Through di LLDB

Build mini language dengan debug info, lalu debug:

Build dengan debug info
clang++ -g -O0 -o kaleidoscope kaleidoscope.cpp \
    $(llvm-config --cxxflags --ldflags --libs core)
Debug dengan LLDB
lldb ./kaleidoscope
(lldb) b main
(lldb) r
(lldb) n  # step over
(lldb) s  # step into
(lldb) v x  # print variable
(lldb) bt  # backtrace

Dengan debug info yang benar, kalian bisa set breakpoint di baris spesifik, melihat nilai variabel, dan step-through kode — bahkan untuk bahasa yang baru kalian ciptakan.

Penutup

Inti yang harus dibawa pulang:

  • DIBuilder menghasilkan DWARF debug info: DIFile, DICompileUnit, DISubprogram, DIVariable.
  • Metadata melekat pada instruksi tanpa mempengaruhi codegen; named metadata bersifat module-level.
  • TBAA membantu optimizer melakukan alias analysis berdasarkan tipe data.
  • Build dengan -g -O0 untuk debugging; attach debug info untuk bahasa custom.

Di episode 15 selanjutnya kita akan membahas Clang AST & libTooling — eksplorasi AST Clang dengan clang -ast-dump, ASTMatchers, ClangTool driver, dan menulis clang-tidy check sendiri. Sampai jumpa di episode 15!

Belajar LLVM - Debug Information & Metadata | Belajar LLVM