8 Without special runtime support, debugging dynamically generated code can be
9 quite painful. Debuggers generally read debug information from object files on
10 disk, but for JITed code there is no such file to look for.
12 In order to hand over the necessary debug info, `GDB established an
13 interface <https://sourceware.org/gdb/onlinedocs/gdb/JIT-Interface.html>`_
14 for registering JITed code with debuggers. LLDB implements it in the
15 JITLoaderGDB plugin. On the JIT side, LLVM MCJIT does implement the interface
18 At a high level, whenever MCJIT generates new machine code, it does so in an
19 in-memory object file that contains the debug information in DWARF format.
20 MCJIT then adds this in-memory object file to a global list of dynamically
21 generated object files and calls a special function
22 ``__jit_debug_register_code`` that the debugger knows about. When the debugger
23 attaches to a process, it puts a breakpoint in this function and associates a
24 special handler with it. Once MCJIT calls the registration function, the
25 debugger catches the breakpoint signal, loads the new object file from the
26 inferior's memory and resumes execution. This way it can obtain debug
27 information for pure in-memory object files.
33 In order to debug code JIT-ed by LLVM, you need GDB 7.0 or newer, which is
34 available on most modern distributions of Linux. The version of GDB that
35 Apple ships with Xcode has been frozen at 6.3 for a while.
41 Due to a regression in release 6.0, LLDB didn't support JITed code debugging for
42 a while. The bug was fixed in mainline recently, so that debugging JITed ELF
43 objects should be possible again from the upcoming release 12.0 on. On macOS the
44 feature must be enabled explicitly using the ``plugin.jit-loader.gdb.enable``
48 Debugging MCJIT-ed code
49 =======================
51 The emerging MCJIT component of LLVM allows full debugging of JIT-ed code with
52 GDB. This is due to MCJIT's ability to use the MC emitter to provide full
53 DWARF debugging information to GDB.
55 Note that lli has to be passed the ``--jit-kind=mcjit`` flag to JIT the code
56 with MCJIT instead of the newer ORC JIT.
61 Consider the following C code (with line numbers added to make the example
66 Sphinx has the ability to automatically number these lines by adding
67 :linenos: on the line immediately following the `.. code-block:: c`, but
68 it looks like garbage; the line numbers don't even line up with the
69 lines. Is this a Sphinx bug, or is it a CSS problem?
73 1 int compute_factorial(int n)
85 13 int main(int argc, char** argv)
89 17 char firstletter = argv[1][0];
90 18 int result = compute_factorial(firstletter - '0');
92 20 // Returned result is clipped at 255...
96 Here is a sample command line session that shows how to build and run this
97 code via ``lli`` inside LLDB:
101 > export BINPATH=/workspaces/llvm-project/build/bin
102 > $BINPATH/clang -g -S -emit-llvm --target=x86_64-unknown-unknown-elf showdebug.c
104 (lldb) target create "/workspaces/llvm-project/build/bin/lli"
105 Current executable set to '/workspaces/llvm-project/build/bin/lli' (x86_64).
106 (lldb) settings set plugin.jit-loader.gdb.enable on
107 (lldb) b compute_factorial
108 Breakpoint 1: no locations (pending).
109 WARNING: Unable to resolve breakpoint to any actual locations.
110 (lldb) run --jit-kind=mcjit showdebug.ll 5
111 1 location added to breakpoint 1
112 Process 21340 stopped
113 * thread #1, name = 'lli', stop reason = breakpoint 1.1
114 frame #0: 0x00007ffff7fd0007 JIT(0x45c2cb0)`compute_factorial(n=5) at showdebug.c:3:11
115 1 int compute_factorial(int n)
124 (lldb) b showdebug.c:9
125 Breakpoint 2: where = JIT(0x45c2cb0)`compute_factorial + 60 at showdebug.c:9:1, address = 0x00007ffff7fd003c
127 Process 21340 resuming
128 Process 21340 stopped
129 * thread #1, name = 'lli', stop reason = breakpoint 2.1
130 frame #0: 0x00007ffff7fd003c JIT(0x45c2cb0)`compute_factorial(n=1) at showdebug.c:9:1
136 11 int main(int argc, char** argv)
141 * thread #1, name = 'lli', stop reason = breakpoint 2.1
142 * frame #0: 0x00007ffff7fd003c JIT(0x45c2cb0)`compute_factorial(n=1) at showdebug.c:9:1
143 frame #1: 0x00007ffff7fd0095 JIT(0x45c2cb0)`main(argc=2, argv=0x00000000046122f0) at showdebug.c:16:18
144 frame #2: 0x0000000002a8306e lli`llvm::MCJIT::runFunction(this=0x000000000458ed10, F=0x0000000004589ff8, ArgValues=ArrayRef<llvm::GenericValue> @ 0x00007fffffffc798) at MCJIT.cpp:554:31
145 frame #3: 0x00000000029bdb45 lli`llvm::ExecutionEngine::runFunctionAsMain(this=0x000000000458ed10, Fn=0x0000000004589ff8, argv=size=0, envp=0x00007fffffffe140) at ExecutionEngine.cpp:467:10
146 frame #4: 0x0000000001f2fc2f lli`main(argc=4, argv=0x00007fffffffe118, envp=0x00007fffffffe140) at lli.cpp:643:18
147 frame #5: 0x00007ffff788c09b libc.so.6`__libc_start_main(main=(lli`main at lli.cpp:387), argc=4, argv=0x00007fffffffe118, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffe108) at libc-start.c:308:16
148 frame #6: 0x0000000001f2dc7a lli`_start + 42
150 Process 21340 stopped
151 * thread #1, name = 'lli', stop reason = step out
152 Return value: (int) $2 = 120
154 frame #0: 0x00007ffff7fd0095 JIT(0x45c2cb0)`main(argc=2, argv=0x00000000046122f0) at showdebug.c:16:9
157 15 char firstletter = argv[1][0];
158 -> 16 int result = compute_factorial(firstletter - '0');
160 18 // Returned result is clipped at 255...
165 Process 21340 stopped
166 * thread #1, name = 'lli', stop reason = step over
167 frame #0: 0x00007ffff7fd0098 JIT(0x45c2cb0)`main(argc=2, argv=0x00000000046122f0) at showdebug.c:19:12
168 16 int result = compute_factorial(firstletter - '0');
170 18 // Returned result is clipped at 255...
175 (lldb) expr result=42
180 Process 21340 resuming
181 Process 21340 exited with status = 42 (0x0000002a)