diff options
author | Doug Evans <dje@google.com> | 2009-08-20 18:02:45 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2009-08-20 18:02:45 +0000 |
commit | 8908432dc48908b505d7c00c7d8288d4071d4c4b (patch) | |
tree | 964a00efb1a08b47462f765bc04f6e26598e4e48 /gdb/doc | |
parent | 85b106a0382155d78c2ec2ab2f15150820459515 (diff) | |
download | gdb-8908432dc48908b505d7c00c7d8288d4071d4c4b.tar.gz |
Add interface for JIT code generation.
* NEWS: Announce JIT interface.
* Makefile.in (SFILES): Add jit.c.
(HFILES_NO_SRCDIR): Add jit.h.
(COMMON_OBS): Add jit.o.
* jit.c: New file.
* jit.h: New file.
* breakpoint.h (enum bptype): Add bp_jit_event to enum.
* breakpoint.c:
(update_breakpoints_after_exec): Delete jit breakpoints after exec.
(bpstat_what): Update event table for bp_jit_event.
(print_it_typical): Added case for bp_jit_event.
(print_one_breakpoint_location): Added case for bp_jit_event.
(allocate_bp_location): Added case for bp_jit_event.
(mention): Added case for bp_jit_event.
(delete_command): Added case for bp_jit_event.
(breakpoint_re_set_one): Added case for bp_jit_event.
(breakpoint_re_set): Added call to jit_inferior_created_hook.
(create_jit_event_breakpoint): New.
* infrun.c (handle_inferior_event): Add handler for jit event.
(follow_exec): Add call to jit_inferior_created_hook.
* doc/gdb.texinfo: Add chapter on JIT interface.
Diffstat (limited to 'gdb/doc')
-rw-r--r-- | gdb/doc/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 131 |
2 files changed, 135 insertions, 0 deletions
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 2801a5c1605..33732166c72 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2009-08-20 Reid Kleckner <reid@kleckner.net> + + * gdb.texinfo: Add chapter on JIT interface. + 2009-08-07 Nick Roberts <nickrob@snap.net.nz> * gdb.texinfo (Server Prefix): Explain that server prefix suppresses diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 4016accdbdf..e5fe6ac3c66 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -159,6 +159,7 @@ software in general. We will miss him. * Emacs:: Using @value{GDBN} under @sc{gnu} Emacs * GDB/MI:: @value{GDBN}'s Machine Interface. * Annotations:: @value{GDBN}'s annotation interface. +* JIT Interface:: Using the JIT debugging interface. * GDB Bugs:: Reporting bugs in @value{GDBN} @@ -25921,6 +25922,136 @@ source which is being displayed. @var{addr} is in the form @samp{0x} followed by one or more lowercase hex digits (note that this does not depend on the language). +@node JIT Interface +@chapter JIT Compilation Interface +@cindex just-in-time compilation +@cindex JIT compilation interface + +This chapter documents @value{GDBN}'s @dfn{just-in-time} (JIT) compilation +interface. A JIT compiler is a program or library that generates native +executable code at runtime and executes it, usually in order to achieve good +performance while maintaining platform independence. + +Programs that use JIT compilation are normally difficult to debug because +portions of their code are generated at runtime, instead of being loaded from +object files, which is where @value{GDBN} normally finds the program's symbols +and debug information. In order to debug programs that use JIT compilation, +@value{GDBN} has an interface that allows the program to register in-memory +symbol files with @value{GDBN} at runtime. + +If you are using @value{GDBN} to debug a program that uses this interface, then +it should work transparently so long as you have not stripped the binary. If +you are developing a JIT compiler, then the interface is documented in the rest +of this chapter. At this time, the only known client of this interface is the +LLVM JIT. + +Broadly speaking, the JIT interface mirrors the dynamic loader interface. The +JIT compiler communicates with @value{GDBN} by writing data into a global +variable and calling a fuction at a well-known symbol. When @value{GDBN} +attaches, it reads a linked list of symbol files from the global variable to +find existing code, and puts a breakpoint in the function so that it can find +out about additional code. + +@menu +* Declarations:: Relevant C struct declarations +* Registering Code:: Steps to register code +* Unregistering Code:: Steps to unregister code +@end menu + +@node Declarations +@section JIT Declarations + +These are the relevant struct declarations that a C program should include to +implement the interface: + +@smallexample +typedef enum +@{ + JIT_NOACTION = 0, + JIT_REGISTER_FN, + JIT_UNREGISTER_FN +@} jit_actions_t; + +struct jit_code_entry +@{ + struct jit_code_entry *next_entry; + struct jit_code_entry *prev_entry; + const char *symfile_addr; + uint64_t symfile_size; +@}; + +struct jit_descriptor +@{ + uint32_t version; + /* This type should be jit_actions_t, but we use uint32_t + to be explicit about the bitwidth. */ + uint32_t action_flag; + struct jit_code_entry *relevant_entry; + struct jit_code_entry *first_entry; +@}; + +/* GDB puts a breakpoint in this function. */ +void __attribute__((noinline)) __jit_debug_register_code() @{ @}; + +/* Make sure to specify the version statically, because the + debugger may check the version before we can set it. */ +struct jit_descriptor __jit_debug_descriptor = @{ 1, 0, 0, 0 @}; +@end smallexample + +If the JIT is multi-threaded, then it is important that the JIT synchronize any +modifications to this global data properly, which can easily be done by putting +a global mutex around modifications to these structures. + +@node Registering Code +@section Registering Code + +To register code with @value{GDBN}, the JIT should follow this protocol: + +@itemize @bullet +@item +Generate an object file in memory with symbols and other desired debug +information. The file must include the virtual addresses of the sections. + +@item +Create a code entry for the file, which gives the start and size of the symbol +file. + +@item +Add it to the linked list in the JIT descriptor. + +@item +Point the relevant_entry field of the descriptor at the entry. + +@item +Set @code{action_flag} to @code{JIT_REGISTER} and call +@code{__jit_debug_register_code}. +@end itemize + +When @value{GDBN} is attached and the breakpoint fires, @value{GDBN} uses the +@code{relevant_entry} pointer so it doesn't have to walk the list looking for +new code. However, the linked list must still be maintained in order to allow +@value{GDBN} to attach to a running process and still find the symbol files. + +@node Unregistering Code +@section Unregistering Code + +If code is freed, then the JIT should use the following protocol: + +@itemize @bullet +@item +Remove the code entry corresponding to the code from the linked list. + +@item +Point the @code{relevant_entry} field of the descriptor at the code entry. + +@item +Set @code{action_flag} to @code{JIT_UNREGISTER} and call +@code{__jit_debug_register_code}. +@end itemize + +If the JIT frees or recompiles code without unregistering it, then @value{GDBN} +and the JIT will leak the memory used for the associated symbol files. + @node GDB Bugs @chapter Reporting Bugs in @value{GDBN} @cindex bugs in @value{GDBN} |