Julia can debug MLIR, kinda

JIT’d thunks are debuggable in gdb, at source level

Break on a mangled thunk name and gdb stops inside the emitted MLIR, by file

and line, with list and disassemble /s working:

cd ~/Desktop/Projects/RepliBuild.jl
gdb -batch -nx \
  -ex 'set pagination off' -ex 'set confirm off' \
  -ex 'handle SIGSEGV nostop noprint pass' \
  -ex 'set breakpoint pending on' \
  -ex 'break _ZNK5Base15get_aEv_thunk' \
  -ex 'run' \
  -ex 'info symbol $pc' \
  -ex 'bt 5' \
  -ex 'x/6i $pc' \
  --args julia --project=. test/mi_test/verify.jl

I got the function setup now to use this and its simpler

rbdbg _ZNK5Base15get_aEv_thunk test/mi_test/verify.jl

This is the break and the julia program. The mlir execution engine has a default I didnt find till recently when I started emitting valid IR…

bool enableGDBNotificationListener = true;
bool enablePerfNotificationListener = true;

this emits the /.debug/jit/**objdump which GDB can step through from julia. Cool stuff, but this basically unlocks a very high level debugger for free working on marshaling thunks for Julia.

This is how Claude explains it works:

The interesting part: those symbols don’t come from MLIR.

libJLCS statically links system LLVM 22.1, but at runtime its ORC calls resolve to Julia’s bundled LLVM 18.1jl — loaded first, global symbol, dynamic linker wins. So Julia’s own JIT and your MLIR thunks register into one shared descriptor list, which is precisely how the interface is specified (one per process). That’s why gdb sees both, and it’s cross-version-safe only because the protocol struct is frozen by gdb’s spec rather than by LLVM’s.