1.. _debugging-jited-code: 2 3============================== 4Debugging JIT-ed Code With GDB 5============================== 6 7.. sectionauthor:: Reid Kleckner and Eli Bendersky 8 9Background 10========== 11 12Without special runtime support, debugging dynamically generated code with 13GDB (as well as most debuggers) can be quite painful. Debuggers generally 14read debug information from the object file of the code, but for JITed 15code, there is no such file to look for. 16 17In order to communicate the necessary debug info to GDB, an interface for 18registering JITed code with debuggers has been designed and implemented for 19GDB and LLVM MCJIT. At a high level, whenever MCJIT generates new machine code, 20it does so in an in-memory object file that contains the debug information in 21DWARF format. MCJIT then adds this in-memory object file to a global list of 22dynamically generated object files and calls a special function 23(``__jit_debug_register_code``) marked noinline that GDB knows about. When 24GDB attaches to a process, it puts a breakpoint in this function and loads all 25of the object files in the global list. When MCJIT calls the registration 26function, GDB catches the breakpoint signal, loads the new object file from 27the inferior's memory, and resumes the execution. In this way, GDB can get the 28necessary debug information. 29 30GDB Version 31=========== 32 33In order to debug code JIT-ed by LLVM, you need GDB 7.0 or newer, which is 34available on most modern distributions of Linux. The version of GDB that 35Apple ships with Xcode has been frozen at 6.3 for a while. LLDB may be a 36better option for debugging JIT-ed code on Mac OS X. 37 38 39Debugging MCJIT-ed code 40======================= 41 42The emerging MCJIT component of LLVM allows full debugging of JIT-ed code with 43GDB. This is due to MCJIT's ability to use the MC emitter to provide full 44DWARF debugging information to GDB. 45 46Note that lli has to be passed the ``-use-mcjit`` flag to JIT the code with 47MCJIT instead of the old JIT. 48 49Example 50------- 51 52Consider the following C code (with line numbers added to make the example 53easier to follow): 54 55.. 56 FIXME: 57 Sphinx has the ability to automatically number these lines by adding 58 :linenos: on the line immediately following the `.. code-block:: c`, but 59 it looks like garbage; the line numbers don't even line up with the 60 lines. Is this a Sphinx bug, or is it a CSS problem? 61 62.. code-block:: c 63 64 1 int compute_factorial(int n) 65 2 { 66 3 if (n <= 1) 67 4 return 1; 68 5 69 6 int f = n; 70 7 while (--n > 1) 71 8 f *= n; 72 9 return f; 73 10 } 74 11 75 12 76 13 int main(int argc, char** argv) 77 14 { 78 15 if (argc < 2) 79 16 return -1; 80 17 char firstletter = argv[1][0]; 81 18 int result = compute_factorial(firstletter - '0'); 82 19 83 20 // Returned result is clipped at 255... 84 21 return result; 85 22 } 86 87Here is a sample command line session that shows how to build and run this 88code via ``lli`` inside GDB: 89 90.. code-block:: bash 91 92 $ $BINPATH/clang -cc1 -O0 -g -emit-llvm showdebug.c 93 $ gdb --quiet --args $BINPATH/lli -use-mcjit showdebug.ll 5 94 Reading symbols from $BINPATH/lli...done. 95 (gdb) b showdebug.c:6 96 No source file named showdebug.c. 97 Make breakpoint pending on future shared library load? (y or [n]) y 98 Breakpoint 1 (showdebug.c:6) pending. 99 (gdb) r 100 Starting program: $BINPATH/lli -use-mcjit showdebug.ll 5 101 [Thread debugging using libthread_db enabled] 102 103 Breakpoint 1, compute_factorial (n=5) at showdebug.c:6 104 6 int f = n; 105 (gdb) p n 106 $1 = 5 107 (gdb) p f 108 $2 = 0 109 (gdb) n 110 7 while (--n > 1) 111 (gdb) p f 112 $3 = 5 113 (gdb) b showdebug.c:9 114 Breakpoint 2 at 0x7ffff7ed404c: file showdebug.c, line 9. 115 (gdb) c 116 Continuing. 117 118 Breakpoint 2, compute_factorial (n=1) at showdebug.c:9 119 9 return f; 120 (gdb) p f 121 $4 = 120 122 (gdb) bt 123 #0 compute_factorial (n=1) at showdebug.c:9 124 #1 0x00007ffff7ed40a9 in main (argc=2, argv=0x16677e0) at showdebug.c:18 125 #2 0x3500000001652748 in ?? () 126 #3 0x00000000016677e0 in ?? () 127 #4 0x0000000000000002 in ?? () 128 #5 0x0000000000d953b3 in llvm::MCJIT::runFunction (this=0x16151f0, F=0x1603020, ArgValues=...) at /home/ebenders_test/llvm_svn_rw/lib/ExecutionEngine/MCJIT/MCJIT.cpp:161 129 #6 0x0000000000dc8872 in llvm::ExecutionEngine::runFunctionAsMain (this=0x16151f0, Fn=0x1603020, argv=..., envp=0x7fffffffe040) 130 at /home/ebenders_test/llvm_svn_rw/lib/ExecutionEngine/ExecutionEngine.cpp:397 131 #7 0x000000000059c583 in main (argc=4, argv=0x7fffffffe018, envp=0x7fffffffe040) at /home/ebenders_test/llvm_svn_rw/tools/lli/lli.cpp:324 132 (gdb) finish 133 Run till exit from #0 compute_factorial (n=1) at showdebug.c:9 134 0x00007ffff7ed40a9 in main (argc=2, argv=0x16677e0) at showdebug.c:18 135 18 int result = compute_factorial(firstletter - '0'); 136 Value returned is $5 = 120 137 (gdb) p result 138 $6 = 23406408 139 (gdb) n 140 21 return result; 141 (gdb) p result 142 $7 = 120 143 (gdb) c 144 Continuing. 145 146 Program exited with code 0170. 147 (gdb) 148