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