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