mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 12:03:41 +08:00
ba44b1a3e0
178 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Simon Marchi
|
ba44b1a3e0 |
gdb: remove SYMBOL_ACLASS_INDEX macro, add getter/setter
Add a getter and a setter for a symbol's aclass index. Remove the corresponding macro and adjust all callers. Change-Id: Ie8c8d732624cfadb714aba5ddafa3d29409b3d39 |
||
Simon Marchi
|
5b6074611e |
gdb: remove SYMTAB_LINETABLE macro, add getter/setter
Add a getter and a setter for a symtab's linetable. Remove the corresponding macro and adjust all callers. Change-Id: I159183fc0ccd8e18ab937b3c2f09ef2244ec6e9c |
||
Simon Marchi
|
af39c5c874 |
gdb: remove COMPUNIT_BLOCKVECTOR macro, add getter/setter
Add a getter and a setter for a compunit_symtab's blockvector. Remove the corresponding macro and adjust all callers. Change-Id: I99484c6619dcbbea7c5d89c72aa660316ca62f64 |
||
Simon Marchi
|
0d9acb4531 |
gdb: remove COMPUNIT_DIRNAME macro, add getter/setter
Add a getter and a setter for a compunit_symtab's dirname. Remove the corresponding macro and adjust all callers. Change-Id: If2f39b295fd26822586485e04a8b8b5aa5cc9b2e |
||
Simon Marchi
|
510860f278 |
gdb: remove COMPUNIT_FILETABS macro
I think that most remaining uses of COMPUNIT_FILETABS intend to get the primary filetab of the compunit_symtab specifically (and not to iterate over all filetabs, for example, those cases would use compunit_filetabs, which has been converted to compunit_symtab::filetabs), so replace mosts uses with compunit_symtab::primary_filetab. In jit.c, function finalize_symtab, we can save the symtab object returned by allocate_symtab and use it, it makes things simpler. Change-Id: I4e51d6d4b40759de8768b61292e5e13c8eae2e38 |
||
Simon Marchi
|
4a620b7e30 |
gdb: include jit_code_entry::symfile_addr value in names of objfiles created by jit reader API
This commit includes the JIT object's symfile address in the names of objfiles created by JIT reader API (e.g., << JIT compiled code at 0x7ffd8a0c77a0 >>). This allows one to at least differentiate one from another. The address is the one that the debugged program has put in jit_code_entry::symfile_addr, and that the JIT reader's read function receives. As we can see in gdb.base/jit-reader-host.c and gdb.base/jit-reader.c, that may not be the actual value of where the JIT-ed code is. But it is a value chosen by the author of the JIT engine and the JIT reader, so including this value in the objfile name may help them correlate the JIT objfiles created by with their logs / data structures. To access this field, we need to pass down a reference to the jit_code_entry. So make jit_dbg_reader_data a structure (instead of an alias for a CORE_ADDR) that includes the address of the code entry in the inferior's address space (the previous meaning of jit_dbg_reader_data) plus a reference to the jit_code_entry as read into GDB's address space. And while at it, pass down the gdbarch, so that we don't have to call target_gdbarch. Co-Authored-By: Jan Vrany <jan.vrany@labware.com> Change-Id: Ib26c4d1bd8de503d651aff89ad2e500cb312afa5 |
||
Joel Brobecker
|
4a94e36819 |
Automatic Copyright Year update after running gdb/copyright.py
This commit brings all the changes made by running gdb/copyright.py as per GDB's Start of New Year Procedure. For the avoidance of doubt, all changes in this commits were performed by the script. |
||
Tom Tromey
|
0fed74615b |
Send jit.c errors to gdb_stderr
jit.c writes some error messages to gdb_stdout, but using gdb_stderr is better. This is part of PR gdb/7233. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=7233 |
||
Andrew Burgess
|
8579fd136a |
gdb/gdbsupport: make xstrprintf and xstrvprintf return a unique_ptr
The motivation is to reduce the number of places where unmanaged pointers are returned from allocation type routines. All of the callers are updated. There should be no user visible changes after this commit. |
||
Simon Marchi
|
ff77083572 |
gdb: call post_create_inferior at end of follow_fork_inferior
GDB doesn't handle well the case of an inferior using the JIT interface to register JIT-ed objfiles and forking. If an inferior registers a code object using the JIT interface and then forks, the child process conceptually has the same code object loaded, so GDB should look it up and learn about it (it currently doesn't). To achieve this, I think it would make sense to have the inferior_created observable called when an inferior is created due to a fork in follow_fork_inferior. The inferior_created observable is currently called both after starting a new inferior and after attaching to an inferior, allowing various sub-components to learn about that new executing inferior. We can see handling a fork child just like attaching to it, so any work done when attaching should also be done in the case of a fork child. Instead of just calling the inferior_created observable, this patch makes follow_fork_inferior call the whole post_create_inferior function. This way, the attach and follow-fork code code paths are more alike. Given that post_create_inferior calls solib_create_inferior_hook, follow_fork_inferior doesn't need to do it itself, so those calls to solib_create_inferior_hook are removed. One question you may have: why not just call post_create_inferior at the places where solib_create_inferior_hook is currently called, instead of after target_follow_fork? - there's something fishy for the second solib_create_inferior_hook call site: at this point we have switched the current program space to the child's, but not the current inferior nor the current thread. So solib_create_inferior_hook (and everything under, including check_for_thread_db, for example) is called with inferior 1 as the current inferior and inferior 2's program space as the current program space. I think that's wrong, because at this point we are setting up inferior 2, and all that code relies on the current inferior. We could just add a switch_to_thread call before it to make inferior 2 the current one, but there are other problems (see below). - solib_create_inferior_hook is currently not called on the `follow_child && detach_fork` path. I think we need to call it, because we still get a new inferior in that case (even though we detach the parent). If we only call post_create_inferior where solib_create_inferior_hook used to be called, then the JIT subcomponent doesn't get informed about the new inferior, and that introduces a failure in the new gdb.base/jit-elf-fork.exp test. - if we try to put the post_create_inferior just after the switch_to_thread that was originally at line 662, or just before the call to target_follow_fork, we introduce a subtle failure in gdb.threads/fork-thread-pending.exp. What happens then is that libthread_db gets loaded (somewhere under post_create_inferior) before the linux-nat target learns about the LWPs (which happens in linux_nat_target::follow_fork). As a result, the ALL_LWPS loop in try_thread_db_load_1 doesn't see the child LWP, and the thread-db target doesn't have the chance to fill in thread_info::priv. A bit later, when the test does "info threads", and thread_db_target::pid_to_str is called, the thread-db target doesn't recognize the thread as one of its own, and delegates the request to the target below. Because the pid_to_str output is not the expected one, the test fails. This tells me that we need to call the process target's follow_fork first, to make the process target create the necessary LWP and thread structures. Then, we can call post_create_inferior to let the other components of GDB do their thing. But then you may ask: check_for_thread_db is already called today, somewhere under solib_create_inferior_hook, and that is before target_follow_fork, why don't we see this ordering problem!? Well, because of the first bullet point: when check_for_thread_db / thread_db_load are called, the current inferior is (erroneously) inferior 1, the parent. Because libthread_db is already loaded for the parent, thread_db_load early returns. check_for_thread_db later gets called by linux_nat_target::follow_fork. At this point, the current inferior is the correct one and the child's LWP exists, so all is well. Since we now call post_create_inferior after target_follow_fork, which calls the inferior_created observable, which calls check_for_thread_db, I don't think linux_nat_target needs to explicitly call check_for_thread_db itself, so that is removed. In terms of testing, this patch adds a new gdb.base/jit-elf-fork.exp test. It makes an inferior register a JIT code object and then fork. It then verifies that whatever the detach-on-fork and follow-fork-child parameters are, GDB knows about the JIT code object in all the inferiors that survive the fork. It verifies that the inferiors can unload that code object. There isn't currently a way to get visibility into GDB's idea of the JIT code objects for each inferior. For the purpose of this test, add the "maintenance info jit" command. There isn't much we can print about the JIT code objects except their load address. So the output looks a bit bare, but it's good enough for the test. gdb/ChangeLog: * NEWS: Mention "maint info jit" command. * infrun.c (follow_fork_inferior): Don't call solib_create_inferior_hook, call post_create_inferior if a new inferior was created. * jit.c (maint_info_jit_cmd): New. (_initialize_jit): Register new command. * linux-nat.c (linux_nat_target::follow_fork): Don't call check_for_thread_db. * linux-nat.h (check_for_thread_db): Remove declaration. * linux-thread-db.c (check_thread_signals): Make static. gdb/doc/ChangeLog: * gdb.texinfo (Maintenance Commands): Mention "maint info jit". gdb/testsuite/ChangeLog: * gdb.base/jit-elf-fork-main.c: New test. * gdb.base/jit-elf-fork-solib.c: New test. * gdb.base/jit-elf-fork.exp: New test. Change-Id: I9a192e55b8a451c00e88100669283fc9ca60de5c |
||
Simon Marchi
|
a154d838a7 |
gdb: add names to unwinders, add debug messages when looking for unwinder
I wrote this while debugging a problem where the expected unwinder for a frame wasn't used. It adds messages to show which unwinders are considered for a frame, why they are not selected (if an exception is thrown), and finally which unwinder is selected in the end. To be able to show a meaningful, human-readable name for the unwinders, add a "name" field to struct frame_unwind, and update all instances to include a name. Here's an example of the output: [frame] frame_unwind_find_by_frame: this_frame=0 [frame] frame_unwind_try_unwinder: trying unwinder "dummy" [frame] frame_unwind_try_unwinder: no [frame] frame_unwind_try_unwinder: trying unwinder "dwarf2 tailcall" [frame] frame_unwind_try_unwinder: no [frame] frame_unwind_try_unwinder: trying unwinder "inline" [frame] frame_unwind_try_unwinder: no [frame] frame_unwind_try_unwinder: trying unwinder "jit" [frame] frame_unwind_try_unwinder: no [frame] frame_unwind_try_unwinder: trying unwinder "python" [frame] frame_unwind_try_unwinder: no [frame] frame_unwind_try_unwinder: trying unwinder "amd64 epilogue" [frame] frame_unwind_try_unwinder: no [frame] frame_unwind_try_unwinder: trying unwinder "i386 epilogue" [frame] frame_unwind_try_unwinder: no [frame] frame_unwind_try_unwinder: trying unwinder "dwarf2" [frame] frame_unwind_try_unwinder: yes gdb/ChangeLog: * frame-unwind.h (struct frame_unwind) <name>: New. Update instances everywhere to include this field. * frame-unwind.c (frame_unwind_try_unwinder, frame_unwind_find_by_frame): Add debug messages. Change-Id: I813f17777422425f0d08b22499817b23922e8ddb |
||
Simon Marchi
|
40cb8ca539 |
gdb: add breakpoint::locations method
Add the breakpoint::locations method, which returns a range that can be used to iterate over a breakpoint's locations. This shortens for (bp_location *loc = b->loc; loc != nullptr; loc = loc->next) into for (bp_location *loc : b->locations ()) Change all the places that I found that could use it. gdb/ChangeLog: * breakpoint.h (bp_locations_range): New. (struct breakpoint) <locations>: New. Use where possible. Change-Id: I1ba2f7d93d57e544e1f8609124587dcf2e1da037 |
||
Tom de Vries
|
6d1a09b77a |
[gdb/breakpoint] Fix assert in jit_event_handler
Consider a minimal test-case test.c: ... int main (void) { return 0; } ... which we can compile into llvm byte code using clang: ... $ clang -g -S -emit-llvm --target=x86_64-unknown-unknown-elf test.c ... and then run using lli, which uses the llvm jit: ... $ lli test.ll ... If we run this under gdb, we run into an assert: ... $ gdb -q -batch -ex run --args /usr/bin/lli test.ll Dwarf Error: Cannot not find DIE at 0x18a936e7 \ [from module libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". src/gdb/jit.c:1178: internal-error: \ void jit_event_handler(gdbarch*, objfile*): \ Assertion `jiter->jiter_data != nullptr' failed. ... This is caused by the following. When running jit_breakpoint_re_set_internal, we first handle libLLVM.so.10.debug, and set a jit breakpoint. Next we handle libLLVM.so.10: ... (gdb) p the_objfile.original_name $42 = 0x2494170 "libLLVM.so.10" ... but the minimal symbols we find are from libLLVM.so.10.debug: ... (gdb) p reg_symbol.objfile.original_name $43 = 0x38e7c50 "libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug" (gdb) p desc_symbol.objfile.original_name $44 = 0x38e7c50 "libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug" ... and consequently, the objf_data is the one from libLLVM.so.10.debug: ... jiter_objfile_data *objf_data = get_jiter_objfile_data (reg_symbol.objfile); ... and so we hit this: ... if (objf_data->cached_code_address == addr) continue; ... and no second jit breakpoint is inserted. Subsequently, the jit breakpoint is triggered and handled, but when finding the symbol for the breakpoint address we get: ... (gdb) p jit_bp_sym.objfile.original_name $52 = 0x2494170 "libLLVM.so.10" ... The assert 'jiter->jiter_data != nullptr' triggers because it checks libLLVM.so.10 while the one with jiter_data setup is libLLVM.so.10.debug. This fixes the assert: ... jiter_objfile_data *objf_data - = get_jiter_objfile_data (reg_symbol.objfile); - = get_jiter_objfile_data (the_objfile); ... but consequently we'll have two jit breakpoints, so we also make sure we don't set a jit breakpoint on separate debug objects like libLLVM.so.10.debug. Tested on x86_64-linux. gdb/ChangeLog: 2021-05-21 Tom de Vries <tdevries@suse.de> PR breakpoint/27889 * jit.c (jit_breakpoint_re_set_internal): Skip separate debug objects. Call get_jiter_objfile_data with the_objfile. |
||
Simon Marchi
|
c90e7d6352 |
gdbsupport, gdb: give names to observers
Give a name to each observer, this will help produce more meaningful debug message. gdbsupport/ChangeLog: * observable.h (class observable) <struct observer> <observer>: Add name parameter. <name>: New field. <attach>: Add name parameter, update all callers. Change-Id: Ie0cc4664925215b8d2b09e026011b7803549fba0 |
||
Simon Marchi
|
54ca900277 |
gdb: convert jit to new-style debug macros
Here's a sample output, with infrun debug enabled as well to show nesting: [infrun] fetch_inferior_event: enter [infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) = [infrun] print_target_wait_results: 4116727.4116727.0 [process 4116727], [infrun] print_target_wait_results: status->kind = stopped, signal = GDB_SIGNAL_TRAP [infrun] handle_inferior_event: status->kind = stopped, signal = GDB_SIGNAL_TRAP [infrun] start_step_over: enter [infrun] start_step_over: stealing global queue of threads to step, length = 0 [infrun] operator(): step-over queue now empty [infrun] start_step_over: exit [infrun] handle_signal_stop: stop_pc=0x555555555229 [infrun] handle_jit_event: handling bp_jit_event [jit] jit_read_descriptor: descriptor_addr = 0x5555555580b0 [jit] jit_register_code: symfile_addr = 0x7000000, symfile_size = 15560 [jit] jit_bfd_try_read_symtab: symfile_addr = 0x7000000, symfile_size = 15560 [jit] jit_breakpoint_re_set_internal: breakpoint_addr = 0x555555555229 [infrun] process_event_stop_test: BPSTAT_WHAT_SINGLE [infrun] process_event_stop_test: no stepping, continue [infrun] resume_1: step=1, signal=GDB_SIGNAL_0, trap_expected=1, current thread [process 4116727] at 0x555555555229 [infrun] prepare_to_wait: prepare_to_wait [infrun] fetch_inferior_event: exit gdb/ChangeLog: * jit.c (jit_debug_printf): New, use throughout file. Change-Id: Ic0f5eb3ffc926fb555de4914e7dc1076ada63a97 |
||
Simon Marchi
|
062eaacbac |
gdb: change jit_debug to a bool
gdb/ChangeLog: * jit.c (jit_debug): Change type to bool. (_initialize_jit): Adjust. Change-Id: Ic2b1eec28eafe8ccb2899f38ddc91ba9703cb38e |
||
Joel Brobecker
|
3666a04883 |
Update copyright year range in all GDB files
This commits the result of running gdb/copyright.py as per our Start of New Year procedure... gdb/ChangeLog Update copyright year range in copyright header of all GDB files. |
||
Mihails Strasuns
|
15cc148fb8 |
gdb: move bfd_open_from_target_memory to gdb_bfd
This function allows to create a BFD handle using an accessible memory range in a target memory. It is currently contained in a JIT module but this functionality may be of wider usefullness - for example, reading ELF binaries contained within a core dump. gdb/ChangeLog: 2020-12-07 Mihails Strasuns <mihails.strasuns@intel.com> * jit.c (mem_bfd*, bfd_open_from_target_memory): Removed. * gdb_bfd.h (gdb_bfd_open_from_target_memory): New function. * gdb_bfd.c (mem_bfd*, gdb_bfd_open_from_target_memory): New functions. |
||
Simon Marchi
|
42a4fec513 |
gdb: add inferior_execd observable
I want to add another action (clearing displaced stepping state) that happens when an inferior execs. I think it would be cleaner to have an observer for this event, rather than have infrun know about each other sub-component. Replace the calls to solib_create_inferior_hook and jit_inferior_created_hook in follow_exec by observers. gdb/ChangeLog: * observable.h (inferior_execd): Declare new observable. * observable.c (inferior_execd): Declare new observable. * infrun.c (follow_exec): Notify inferior_execd observer. * jit.c (jit_inferior_created_hook): Make static. (_initialize_jit): Register inferior_execd observer. * jit.h (jit_inferior_created_hook): Remove declaration. * solib.c (_initialize_solib): Register inferior_execd observer. Change-Id: I000cce00094e23baa67df693d912646b6ae38e44 |
||
Simon Marchi
|
324956617c |
gdb: make jit.c use the inferior_created inferior parameter
Use the inferior parameter now available in jit_inferior_created_hook. It is passed down to jit_inferior_init, which uses it as much as possible instead of the current inferior or current program space. gdb/ChangeLog: * jit.c (jit_reader_load_command): Pass current inferior. (jit_inferior_init): Change parameter type to inferior, use it. (jit_inferior_created): Remove. (jit_inferior_created_hook): Pass inferior parameter down. (_initialize_jit): Use jit_inferior_created_hook instead of jit_inferior_created. * jit.h (jit_inferior_created_hook): Add inferior parameter. * infrun.c (follow_exec): Pass inferior to jit_inferior_created_hook. Change-Id: If3a2114a933370dd313d5abd623136d273cdb8fa |
||
Simon Marchi
|
a0ff652f4c |
gdb: add inferior parameter to inferior_created observable
I think it would make sense for the inferior_created observable to say which inferior is being dealt with, rather than relying on it being the current inferior. This patch adds an inferior parameter to inferior_created, but does not change the callbacks to use it. gdb/ChangeLog: * aix-thread.c (aix_thread_inferior_created): Add inferior parameter. * bsd-uthread.c (bsd_uthread_inferior_created): Likewise. * dummy-frame.c (cleanup_dummy_frames): Likewise. * jit.c (jit_inferior_created): Likewise. * linux-thread-db.c (thread_db_inferior_created): Likewise. * m68k-linux-tdep.c (m68k_linux_inferior_created): Likewise. * observable.h (inferior_created): Likewise. * ravenscar-thread.c (ravenscar_inferior_created): Likewise. * symfile-mem.c (add_vsyscall_page): Likewise. * infcmd.c (post_create_inferior): Pass inferior argument. Change-Id: I2543d19ff055a9df6b269929faea10b27d2adc5e |
||
Simon Marchi
|
a7aba2668a |
gdb: remove arguments from inferior_created observable
I noticed that non of the listeners of the inferior_created observable used either of the arguments. Remove them. This in turn allows removing the target parameter of post_create_inferior. Tested only by rebuilding. gdb/ChangeLog: * observable.h <inferior_created>: Remove parameters. Update all listeners. * inferior.h (post_create_inferior): Remove target parameter. Update all callers. Change-Id: I8944cefdc4447ed5347dc927b75abf1e7a0e27e6 |
||
Tom Tromey
|
db92ac4568 |
Use arrays rather than pointers for global string constants
My understanding is that it's mildly better to use a static const array, as opposed to a "const char *", for a global string constant, when possible. This makes sense to me because the pointer requires a load from an address, whereas the array is just the address. So, I searched for these in gdb and gdbserver. This patch fixes the ones I found. gdb/ChangeLog 2020-09-15 Tom Tromey <tromey@adacore.com> * unittests/memory-map-selftests.c (valid_mem_map): Now array. * ui-style.c (ansi_regex_text): Now array. * rust-exp.y (number_regex_text): Now array. * linespec.c (linespec_quote_characters): Now array. * jit.c (jit_break_name, jit_descriptor_name, reader_init_fn_sym): Now arrays. gdbserver/ChangeLog 2020-09-15 Tom Tromey <tromey@adacore.com> * linux-x86-low.cc (xmltarget_i386_linux_no_xml) (xmltarget_amd64_linux_no_xml): Now arrays. |
||
Simon Marchi
|
a7b4ff4f0a |
gdb/jit: skip jit symbol lookup if already detected the symbols don't exist
To detect whether an objfile is a JITer, we lookup JIT interface symbols in the objfile. If an objfile does not have these symbols, we conclude that it is not a JITer. An objfile that does not have the symbols will never have them. Therefore, once we do a lookup and find out that the objfile does not have JIT symbols, just set a flag so that we can skip symbol lookup for that objfile the next time we reset JIT breakpoints. gdb/ChangeLog: 2020-07-22 Simon Marchi <simon.marchi@polymtl.ca> Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * objfiles.h (struct objfile) <skip_jit_symbol_lookup>: New field. * jit.c (jit_breakpoint_re_set_internal): Use the `skip_jit_symbol_lookup` field. |
||
Simon Marchi
|
2340e834df |
gdb/jit: apply minor cleanup and modernization
gdb/ChangeLog: 2020-07-22 Simon Marchi <simon.marchi@polymtl.ca> Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * jit.c (jit_read_descriptor): Define the descriptor address once, use twice. (jit_breakpoint_deleted): Move the declaration of the loop variable `iter` into the loop header. (jit_breakpoint_re_set_internal): Move the declaration of the local variable `objf_data` to the first point of definition. (jit_event_handler): Move the declaration of local variables `code_entry`, `entry_addr`, and `objf` to their first point of use. Rename `objf` to `jited`. |
||
Simon Marchi
|
c1072906f1 |
gdb/jit: remove jiter_objfile_data -> objfile back-link
This is no longer needed, remove it. gdb/ChangeLog: 2020-07-22 Simon Marchi <simon.marchi@polymtl.ca> * jit.h (struct jiter_objfile_data) <jiter_objfile_data, objfile>: Remove. * jit.c (get_jiter_objfile_data): Update. |
||
Tankut Baris Aktemur
|
c8474dc353 |
gdb/jit: enable tracking multiple JITer objfiles
GDB's JIT handler stores an objfile (and data associated with it) per program space to keep track of JIT breakpoint information. This assumes that there is at most one JITer objfile in the program space. However, there may be multiple. If so, only the first JITer's hook breakpoints would be realized and the JIT events from the other JITers would be missed. This patch removes that assumption, allowing an arbitrary number of objfiles within a program space to be JITers. - The "unique" program_space -> JITer objfile pointer in jit_program_space_data is removed. In fact, jit_program_space_data becomes empty, so it is removed entirely. - jit_breakpoint_deleted is modified, it now has to assume that any objfile in a program space is a potential JITer. It now iterates on all objfiles, checking if they are indeed JITers, and if they are, whether the deleted breakpoint belongs to them. - jit_breakpoint_re_set_internal also has to assume that any objfile in a program space is a potential JITer. It creates (or updates) one jiter_objfile_data structure for each JITer it finds. - Same for jit_inferior_init. It now iterates all objfiles to read the initial JIT object list. gdb/ChangeLog: 2020-07-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> Simon Marchi <simon.marchi@polymtl.ca> * jit.c (struct jit_program_space_data): Remove. (jit_program_space_key): Remove. (jiter_objfile_data::~jiter_objfile_data): Remove program space stuff. (get_jit_program_space_data): Remove. (jit_breakpoint_deleted): Iterate on all of the program space's objfiles. (jit_inferior_init): Likewise. (jit_breakpoint_re_set_internal): Likewise. Also change return type to void. (jit_breakpoint_re_set): Pass current_program_space to jit_breakpoint_re_set_internal. gdb/testsuite/ChangeLog: 2020-07-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.base/jit-reader-simple.exp: Add a scenario for a binary that loads two JITers. |
||
Simon Marchi
|
77208eb7e2 |
gdb/jit: move cached_code_address and jit_breakpoint to jiter_objfile_data
This is in preparation for allowing more than one JITer objfile per program space. Once we do that, each JITer objfile will have its own JIT breakpoint (on the __jit_debug_register_code function it provides). The cached_code_address field is just the runtime / relocated address of that symbol. Since they are going to become JITer-objfile-specific and not program-space-specific, move these fields from jit_program_space_data to jiter_objfile_data. gdb/ChangeLog: 2020-07-22 Simon Marchi <simon.marchi@polymtl.ca> * jit.h (struct jiter_objfile_data) <cached_code_address, jit_breakpoint>: Move to here from ... * jit.c (jit_program_space_data): ... here. (jiter_objfile_data::~jiter_objfile_data): Update. (jit_breakpoint_deleted): Update. (jit_breakpoint_re_set_internal): Update. |
||
Simon Marchi
|
8c1c720faa |
gdb/jit: apply some simplifications and assertions
Following patch "gdb/jit: split jit_objfile_data in two", there are some simplifications we can make. The invariants described there mean that we can assume / assert some things instead of checking them using conditionals. If an instance of jiter_objfile_data exists for a given objfile, it's because the required JIT interface symbols were found. Therefore, in ~jiter_objfile_data, the `register_code` field can't be NULL. It was previously used to differentiate a jit_objfile_data object used for a JITer vs a JITed. We can remove that check. If an instance of jiter_objfile_data exists for a given objfile, it's because it's the sole JITer objfile in the scope of its program space (jit_program_space_data::objfile points to it). At the moment, jit_breakpoint_re_set_internal won't create a second instance of jiter_objfile_data for a given program space. Therefore, it's not necessary to check for `ps_data != NULL` in ~jiter_objfile_data: we know a jit_program_space_data for that program space exists. We also don't need to check for `ps_data->objfile == this->objfile`, because we know the objfile is the sole JITer in this program space. Replace these two conditions with assertions. A pre-condition for calling the jit_read_descriptor function (which is respected in the two call sites) is that the objfile `jiter` _is_ a JITer - it already has a jiter_objfile_data attached to it. When a jiter_objfile_data exists, its `descriptor` field is necessarily set: had the descriptor symbol not been found, jit_breakpoint_re_set_internal would not have created the jiter_objfile_data. Remove the check and early return in jit_read_descriptor. Access objfile's `jiter_data` field directly instead of calling `get_jiter_objfile_data` (which creates the jiter_objfile_data if it doesn't exist yet) and assert that the result is not nullptr. Finally, `jit_event_handler` is always passed a JITer objfile. So, add an assertion to ensure that. gdb/ChangeLog: 2020-07-22 Simon Marchi <simon.marchi@polymtl.ca> * jit.c (jiter_objfile_data::~jiter_objfile_data): Remove some checks. (jit_read_descriptor): Remove NULL check. (jit_event_handler): Add an assertion. |
||
Simon Marchi
|
0e74a041c0 |
gdb/jit: split jit_objfile_data in two
The jit_objfile_data is currently used to hold information about both objfiles that are the result of JIT compilation (JITed) and objfiles that can produce JITed objfiles (JITers). I think that this double use of the type is confusing, and that things would be more obvious if we had one type for each role. This patch splits it into: - jited_objfile_data: for data about an objfile that is the result of a JIT compilation - jiter_objfile_data: for data about an objfile which produces JITed objfiles There are now two JIT-related fields in an objfile, one for each kind. With this change, the following invariants hold: - an objfile has a non-null `jiter_data` field iff it defines the required symbols of the JIT interface - an objfile has a non-null `jited_data` field iff it is the product of JIT compilation (has been produced by some JITer) gdb/ChangeLog: 2020-07-22 Simon Marchi <simon.marchi@polymtl.ca> * jit.h (struct jit_objfile_data): Split into... (struct jiter_objfile_data): ... this ... (struct jited_objfile_data): ... and this. * objfiles.h (struct objfile) <jit_data>: Remove. <jiter_data, jited_data>: New fields. * jit.c (jit_objfile_data::~jit_objfile_data): Rename to ... (jiter_objfile_data::~jiter_objfile_data): ... this. (get_jit_objfile_data): Rename to ... (get_jiter_objfile_data): ... this. (add_objfile_entry): Update. (jit_read_descriptor): Use get_jiter_objfile_data. (jit_find_objf_with_entry_addr): Use objfile's jited_data field. (jit_breakpoint_re_set_internal): Use get_jiter_objfile_data. (jit_inferior_exit_hook): Use objfile's jited_data field. |
||
Simon Marchi
|
238b5c9f08 |
gdb/jit: link to jit_objfile_data directly from the objfile struct
Remove the use of objfile_data to associate a jit_objfile_data with an objfile. Instead, directly link to a jit_objfile_data from an objfile struct. The goal is to eliminate unnecessary abstraction. The free_objfile_data function naturally becomes the destructor of jit_objfile_data. However, free_objfile_data accesses the objfile to which the data is attached, which the destructor of jit_objfile_data doesn't have access to. To work around this, add a backlink to the owning objfile in jit_objfile_data. This is however temporary, it goes away in a subsequent patch. gdb/ChangeLog: 2020-07-22 Simon Marchi <simon.marchi@polymtl.ca> * jit.h: Forward-declare `struct minimal_symbol`. (struct jit_objfile_data): Migrate to here from jit.c; also add a constructor, destructor, and an objfile* field. * jit.c (jit_objfile_data): Remove. (struct jit_objfile_data): Migrate from here to jit.h. (jit_objfile_data::~jit_objfile_data): New destructor implementation with code moved from free_objfile_data. (free_objfile_data): Delete. (get_jit_objfile_data): Update to use the jit_data field of objfile. (jit_find_objf_with_entry_addr): Ditto. (jit_inferior_exit_hook): Ditto. (_initialize_jit): Remove the call to register_objfile_data_with_cleanup. * objfiles.h (struct objfile) <jit_data>: New field. |
||
Tankut Baris Aktemur
|
fe053b9e85 |
gdb/jit: pass the jiter objfile as an argument to jit_event_handler
This is a refactoring that adds a new parameter to the `jit_event_handler` function: the JITer objfile. The goal is to distinguish which JITer triggered the JIT event, in case there are multiple JITers -- a capability that is added in a subsequent patch. gdb/ChangeLog: 2020-07-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * jit.h: Forward-declare `struct objfile`. (jit_event_handler): Add a second parameter, the JITer objfile. * jit.c (jit_read_descriptor): Change the signature to take the JITer objfile as an argument instead of the jit_program_space_data. (jit_inferior_init): Update the call to jit_read_descriptor. (jit_event_handler): Use the new JITer objfile argument when calling jit_read_descriptor. * breakpoint.c (handle_jit_event): Update the call to jit_event_handler to pass the JITer objfile. |
||
Tankut Baris Aktemur
|
bd920864f3 |
gdb/jit: return bool in jit_breakpoint_re_set_internal and jit_read_descriptor
This is a minor refactoring that converts the return type of jit_read_descriptor and jit_breakpoint_re_set_internal functions from 'int' to 'bool'. The return value logic of jit_breakpoint_re_set_internal has been reversed. With this patch it now returns true if the jit breakpoint has been successfully initialized. gdb/ChangeLog: 2020-06-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * jit.c (jit_read_descriptor): Use bool as the return type. (jit_breakpoint_re_set_internal): Use bool as the return type. Invert the return value logic; return true if the jit breakpoint has been successfully initialized. (jit_inferior_init): Update the call to jit_breakpoint_re_set_internal. |
||
Tom Tromey
|
8c14c3a373 |
Remove allocate_symbol et al
This removes allocate_symbol, allocate_template_symbol, and initialize_objfile_symbol in favor of changing the default values for symbol members, and updating the one per-arch caller. gdb/ChangeLog 2020-05-15 Tom Tromey <tom@tromey.com> * language.c (language_alloc_type_symbol): Set SYMBOL_SECTION. * symtab.c (initialize_objfile_symbol): Remove. (allocate_symbol): Remove. (allocate_template_symbol): Remove. * dwarf2/read.c (fixup_go_packaging): Use "new". (new_symbol): Use "new". (read_variable): Don't call initialize_objfile_symbol. Use "new". (read_func_scope): Use "new". * xcoffread.c (process_xcoff_symbol): Don't call initialize_objfile_symbol. (SYMBOL_DUP): Remove. * coffread.c (process_coff_symbol, coff_read_enum_type): Use "new". * symtab.h (allocate_symbol, initialize_objfile_symbol) (allocate_template_symbol): Don't declare. (struct symbol): Add copy constructor. Change defaults. * jit.c (finalize_symtab): Use "new". * ctfread.c (ctf_add_enum_member_cb, new_symbol, ctf_add_var_cb): Use "new". * stabsread.c (patch_block_stabs, define_symbol, read_enum_type) (common_block_end): Use "new". * mdebugread.c (parse_symbol): Use "new". (new_symbol): Likewise. |
||
Tom Tromey
|
08feed99cb |
Change get_objfile_arch to a method on objfile
This changes get_objfile_arch to be a new inline method, objfile::arch. To my surprise, this function came up while profiling DWARF psymbol reading. Making this change improved performance from 1.986 seconds to 1.869 seconds. Both measurements were done by taking the mean of 10 runs on a fixed copy of the gdb executable. gdb/ChangeLog 2020-04-18 Tom Tromey <tom@tromey.com> * xcoffread.c (enter_line_range, scan_xcoff_symtab): Update. * value.c (value_fn_field): Update. * valops.c (find_function_in_inferior) (value_allocate_space_in_inferior): Update. * tui/tui-winsource.c (tui_update_source_windows_with_line): Update. * tui/tui-source.c (tui_source_window::set_contents): Update. * symtab.c (lookup_global_or_static_symbol) (find_function_start_sal_1, skip_prologue_sal) (print_msymbol_info, find_gnu_ifunc, symbol_arch): Update. * symmisc.c (dump_msymbols, dump_symtab_1) (maintenance_print_one_line_table): Update. * symfile.c (init_entry_point_info, section_is_mapped) (list_overlays_command, simple_read_overlay_table) (simple_overlay_update_1): Update. * stap-probe.c (handle_stap_probe): Update. * stabsread.c (dbx_init_float_type, define_symbol) (read_one_struct_field, read_enum_type, read_range_type): Update. * source.c (info_line_command): Update. * python/python.c (gdbpy_source_objfile_script) (gdbpy_execute_objfile_script): Update. * python/py-type.c (save_objfile_types): Update. * python/py-objfile.c (py_free_objfile): Update. * python/py-inferior.c (python_new_objfile): Update. * psymtab.c (psym_find_pc_sect_compunit_symtab, dump_psymtab) (dump_psymtab_addrmap_1, maintenance_info_psymtabs) (maintenance_check_psymtabs): Update. * printcmd.c (info_address_command): Update. * objfiles.h (struct objfile) <arch>: New method, from get_objfile_arch. (get_objfile_arch): Don't declare. * objfiles.c (get_objfile_arch): Remove. (filter_overlapping_sections): Update. * minsyms.c (msymbol_is_function): Update. * mi/mi-symbol-cmds.c (mi_cmd_symbol_list_lines) (output_nondebug_symbol): Update. * mdebugread.c (parse_symbol, basic_type, parse_partial_symbols) (mdebug_expand_psymtab): Update. * machoread.c (macho_add_oso_symfile): Update. * linux-tdep.c (linux_infcall_mmap, linux_infcall_munmap): Update. * linux-fork.c (checkpoint_command): Update. * linespec.c (convert_linespec_to_sals): Update. * jit.c (finalize_symtab): Update. * infrun.c (insert_exception_resume_from_probe): Update. * ia64-tdep.c (ia64_find_unwind_table): Update. * hppa-tdep.c (internalize_unwinds): Update. * gdbtypes.c (get_type_arch, init_float_type, objfile_type): Update. * gcore.c (call_target_sbrk): Update. * elfread.c (record_minimal_symbol, elf_symtab_read) (elf_rel_plt_read, elf_gnu_ifunc_record_cache) (elf_gnu_ifunc_resolve_by_got): Update. * dwarf2/read.c (create_addrmap_from_index) (create_addrmap_from_aranges, dw2_find_pc_sect_compunit_symtab) (read_debug_names_from_section) (process_psymtab_comp_unit_reader, add_partial_symbol) (add_partial_subprogram, process_full_comp_unit) (read_file_scope, read_func_scope, read_lexical_block_scope) (read_call_site_scope, dwarf2_ranges_read) (dwarf2_record_block_ranges, dwarf2_add_field) (mark_common_block_symbol_computed, read_tag_pointer_type) (read_tag_string_type, dwarf2_init_float_type) (dwarf2_init_complex_target_type, read_base_type) (partial_die_info::read, partial_die_info::read) (read_attribute_value, dwarf_decode_lines_1, new_symbol) (dwarf2_fetch_die_loc_sect_off): Update. * dwarf2/loc.c (dwarf2_find_location_expression) (class dwarf_evaluate_loc_desc, rw_pieced_value) (dwarf2_evaluate_loc_desc_full, dwarf2_locexpr_baton_eval) (dwarf2_loc_desc_get_symbol_read_needs) (locexpr_describe_location_piece, locexpr_describe_location_1) (loclist_describe_location): Update. * dwarf2/index-write.c (write_debug_names): Update. * dwarf2/frame.c (dwarf2_build_frame_info): Update. * dtrace-probe.c (dtrace_process_dof): Update. * dbxread.c (read_dbx_symtab, dbx_end_psymtab) (process_one_symbol): Update. * ctfread.c (ctf_init_float_type, read_base_type): Update. * coffread.c (coff_symtab_read, enter_linenos, decode_base_type) (coff_read_enum_type): Update. * cli/cli-cmds.c (edit_command, list_command): Update. * buildsym.c (buildsym_compunit::finish_block_internal): Update. * breakpoint.c (create_overlay_event_breakpoint) (create_longjmp_master_breakpoint) (create_std_terminate_master_breakpoint) (create_exception_master_breakpoint, get_sal_arch): Update. * block.c (block_gdbarch): Update. * annotate.c (annotate_source_line): Update. |
||
Andrew Burgess
|
8c95582da8 |
gdb: Add support for tracking the DWARF line table is-stmt field
This commit brings support for the DWARF line table is_stmt field to GDB. The is_stmt field is used by the compiler when a single source line is split into multiple assembler instructions, especially if the assembler instructions are interleaved with instruction from other source lines. The compiler will set the is_stmt flag false from some instructions from the source lines, these instructions are not a good place to insert a breakpoint in order to stop at the source line. Instructions which are marked with the is_stmt flag true are a good place to insert a breakpoint for that source line. Currently GDB ignores all instructions for which is_stmt is false. This is fine in a lot of cases, however, there are some cases where this means the debug experience is not as good as it could be. Consider stopping at a random instruction, currently this instruction will be attributed to the last line table entry before this point for which is_stmt was true - as these are the only line table entries that GDB tracks. This can easily be incorrect in code with even a low level of optimisation. With is_stmt tracking in place, when stopping at a random instruction we now attribute the instruction back to the real source line, even when is_stmt is false for that instruction in the line table. When inserting breakpoints we still select line table entries for which is_stmt is true, so the breakpoint placing behaviour should not change. When stepping though code (at the line level, not the instruction level) we will still stop at instruction where is_stmt is true, I think this is more likely to be the desired behaviour. Instruction stepping is, of course, unchanged, stepping one instruction at a time, but we should now report more accurate line table information with each instruction step. The original motivation for this work was a patch posted by Bernd here: https://sourceware.org/ml/gdb-patches/2019-11/msg00792.html As part of that thread it was suggested that many issues would be resolved if GDB supported line table views, this isn't something I've attempted in this patch, though reading the spec, it seems like this would be a useful feature to support in GDB in the future. The spec is here: http://dwarfstd.org/ShowIssue.php?issue=170427.1 And Bernd gives a brief description of the benefits here: https://sourceware.org/ml/gdb-patches/2020-01/msg00147.html With that all said, I think that there is benefit to having proper is_stmt support regardless of whether we have views support, so I think we should consider getting this in first, and then building view support on top of this. The gdb.cp/step-and-next-inline.exp test is based off a test proposed by Bernd Edlinger in this message: https://sourceware.org/ml/gdb-patches/2019-12/msg00842.html gdb/ChangeLog: * buildsym-legacy.c (record_line): Pass extra parameter to record_line. * buildsym.c (buildsym_compunit::record_line): Take an extra parameter, reduce duplication in the line table, and record the is_stmt flag in the line table. * buildsym.h (buildsym_compunit::record_line): Add extra parameter. * disasm.c (do_mixed_source_and_assembly_deprecated): Ignore non-statement lines. * dwarf2/read.c (dwarf_record_line_1): Add extra parameter, pass this to the symtab builder. (dwarf_finish_line): Pass extra parameter to dwarf_record_line_1. (lnp_state_machine::record_line): Pass a suitable is_stmt flag through to dwarf_record_line_1. * infrun.c (process_event_stop_test): When stepping, don't stop at a non-statement instruction, and only refresh the step info when we land in the middle of a line's range. Also add an extra comment. * jit.c (jit_symtab_line_mapping_add_impl): Initialise is_stmt field. * record-btrace.c (btrace_find_line_range): Only record lines marked as is-statement. * stack.c (frame_show_address): Show the frame address if we are in a non-statement sal. * symmisc.c (dump_symtab_1): Print the is_stmt flag. (maintenance_print_one_line_table): Print a header for the is_stmt column, and include is_stmt information in the output. * symtab.c (find_pc_sect_line): Find lines marked as statements in preference to non-statements. (find_pcs_for_symtab_line): Prefer is-statement entries. (find_line_common): Likewise. * symtab.h (struct linetable_entry): Add is_stmt field. (struct symtab_and_line): Likewise. * xcoffread.c (arrange_linetable): Initialise is_stmt field when arranging the line table. gdb/testsuite/ChangeLog: * gdb.cp/step-and-next-inline.cc: New file. * gdb.cp/step-and-next-inline.exp: New file. * gdb.cp/step-and-next-inline.h: New file. * gdb.dwarf2/dw2-is-stmt.c: New file. * gdb.dwarf2/dw2-is-stmt.exp: New file. * gdb.dwarf2/dw2-is-stmt-2.c: New file. * gdb.dwarf2/dw2-is-stmt-2.exp: New file. * gdb.dwarf2/dw2-ranges-base.exp: Update line table pattern. |
||
Tom Tromey
|
4e7625fde2 |
Make "gnutarget" const
I noticed that gnutarget was not "const". Since writing through this pointer would probably be a bug, I think it ought to be. This patch makes the change. gdb/ChangeLog 2020-03-04 Tom Tromey <tom@tromey.com> * jit.c (bfd_open_from_target_memory): Make "target" const. * corefile.c (gnutarget): Now const. * gdbcore.h (gnutarget): Now const. |
||
Simon Marchi
|
6c2659886f |
gdb: add back declarations for _initialize functions
I'd like to enable the -Wmissing-declarations warning. However, it
warns for every _initialize function, for example:
CXX dcache.o
/home/smarchi/src/binutils-gdb/gdb/dcache.c: In function ‘void _initialize_dcache()’:
/home/smarchi/src/binutils-gdb/gdb/dcache.c:688:1: error: no previous declaration for ‘void _initialize_dcache()’ [-Werror=missing-declarations]
_initialize_dcache (void)
^~~~~~~~~~~~~~~~~~
The only practical way forward I found is to add back the declarations,
which were removed by this commit:
commit
|
||
Joel Brobecker
|
b811d2c292 |
Update copyright year range in all GDB files.
gdb/ChangeLog: Update copyright year range in all GDB files. |
||
Christian Biesinger
|
4d4eaa3005 |
Make symbol_set_names a member function
This also renames it to make it clearer that this is not a cheap function (to compute_and_set_names). Also renames name to m_name to make the implementation of the renamed function more readable. Most of the places that access sym->m_name directly were also changed to call linkage_name () instead, to make it clearer which name they are accessing. gdb/ChangeLog: 2019-12-26 Christian Biesinger <cbiesinger@google.com> * ada-lang.c (ada_decode_symbol): Update. * buildsym.c (add_symbol_to_list): Update. * coffread.c (process_coff_symbol): Update. * ctfread.c (ctf_add_enum_member_cb): Update. (new_symbol): Update. (ctf_add_var_cb): Update. * dwarf2read.c (fixup_go_packaging): Update. (dwarf2_compute_name): Update. (new_symbol): Update. * jit.c (finalize_symtab): Update. * language.c (language_alloc_type_symbol): Update. * mdebugread.c (new_symbol): Update. * minsyms.c (minimal_symbol_reader::record_full): Update. (minimal_symbol_reader::install): Update. * psymtab.c (print_partial_symbols): Update. (psymbol_hash): Update. (psymbol_compare): Update. (add_psymbol_to_bcache): Update. (maintenance_check_psymtabs): Update. * stabsread.c (define_symbol): Update. * symtab.c (symbol_set_names): Rename to... (general_symbol_info::compute_and_set_names): ...this. (general_symbol_info::natural_name): Update. (general_symbol_info::search_name): Update. (fixup_section): Update. * symtab.h (struct general_symbol_info) <name>: Rename to... <m_name>: ...this. <compute_and_set_names>: Rename from... (symbol_set_names): ...this. (SYMBOL_SET_NAMES): Remove. (struct symbol) <ctor>: Update. Change-Id: I8da1f10cab4e0b89f19d5750fa4e6e2ac8d2b24f |
||
Simon Marchi
|
0394eed15c |
jit: make gdb_symtab::blocks an std::forward_list
This patch changes the gdb_symtab::blocks manually maintained linked list to be an std::forward_list, simplifying memory management. Currently, the list is sorted as blocks are created. With an std::forward_list, it is easier (and probably a bit more efficient) to sort them once at the end, so this is what I did. A note about the comment on the "next" field: /* gdb_blocks are linked into a tree structure. Next points to the next node at the same depth as this block and parent to the parent gdb_block. */ I don't think it's true that "next" points to the next node at the same depth. All nodes are in a simple singly linked list, so necessarily some node will point to some other node that isn't at the same depth. gdb/ChangeLog: * jit.c (struct gdb_block) <next>: Remove field. (struct gdb_symtab) <~gdb_symtab>: Remove. <blocks>: Change type to std::forward_list<gdb_block>. (compare_block): Remove. (jit_block_open_impl): Adjust to std::forward_list. Place the new block at the beginning, don't mind about sorting. (finalize_symtab): Adjust to std::forward_list, sort the blocks list before using it. |
||
Simon Marchi
|
b61121178e |
jit: c++-ify gdb_block
Add a constructor to gdb_block, change the name field to be a gdb::unique_xmalloc_ptr. This is in preparation for using an std::forward_list<gdb_block> in the next patch. gdb/ChangeLog: * jit.c (struct gdb_block): Add constructor, initialize real_block and next fields. <name>: Change type to gdb::unique_xmalloc_ptr. (struct gdb_symtab) <~gdb_symtab>: Free blocks with delete. (jit_block_open_impl): Allocate gdb_block with new. (finalize_symtab): Adjust to gdb::unique_xmalloc_ptr. |
||
Simon Marchi
|
1b61f46da5 |
jit: make gdb_object::symtabs an std::forward_list
Replace the manual linked list with an std::forward_list, simplifying the memory management. This requires allocating gdb_object with new and free'ing it with delete. gdb/ChangeLog: * jit.c: Include forward_list. (struct gdb_symtab) <next>: Remove field. (struct gdb_object) <symtabs>: Change type to std::forward_list<gdb_symtab>. (jit_object_open_impl): Allocate gdb_object with new. (jit_symtab_open_impl): Adjust to std::forward_list. (finalize_symtab): Don't delete symtab. (jit_object_close_impl): Adjust to std::forward_list. Free gdb_object with delete. |
||
Simon Marchi
|
8986718429 |
jit: c++-ify gdb_symtab
This patch makes the gdb_symtab bit more c++y, in preparation for the next patch that will use an std::forward_list<gdb_symtab>. It changes the fields to use automatic memory management, in the form of std::string and gdb::unique_xmalloc_ptr, and adds a constructor and a destructor. gdb/ChangeLog: * jit.c (struct gdb_symtab): Add constructor, destructor, initialize fields. <linetable>: Change type to unique_xmalloc_ptr. <file_name>: Change type to std::string. (jit_symtab_open_impl): Allocate gdb_symtab with new. (jit_symtab_line_mapping_add_impl): Adjust. (finalize_symtab): Adjust, call delete on stab. |
||
Simon Marchi
|
d043f8c867 |
Fix double-free when creating more than one block in JIT debug info reader
A double-free happens when using a JIT debug info reader that creates more than one block. In the loop that frees blocks in finalize_symtab, at the very end, the gdb_block_iter_tmp variable is set initially, but not changed as the loop advances. If we have two blocks, the first iteration frees the first block, the second iteration frees the second block, but the third iteration tries to free the second block again, as gdb_block_iter_tmp keeps pointing on the second block. Fix it by assigning the gdb_block_iter_tmp variable in the loop. I have improved the jit-reader.exp test to cover this case, by adding a second "JIT-ed" function and creating a block for it. I have renamed the existing function to something I find a bit more descriptive. There are no significant changes to jit-reader.exp itself, only updates following the renaming. The important changes are in jithost.c (generate a new function) and in jitreader.c (create a gdb_block for that function). This was found because of an ASan report: $ ./gdb testsuite/outputs/gdb.base/jit-reader/jit-reader -ex "jit-reader-load /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/jit-reader/jitreader.so" -ex r Reading symbols from testsuite/outputs/gdb.base/jit-reader/jit-reader... Starting program: /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/jit-reader/jit-reader ================================================================= ==1751048==ERROR: AddressSanitizer: heap-use-after-free on address 0x604000042eb8 at pc 0x5650ef8eec88 bp 0x7ffe52767290 sp 0x7ffe52767280 READ of size 8 at 0x604000042eb8 thread T0 #0 0x5650ef8eec87 in finalize_symtab /home/simark/src/binutils-gdb/gdb/jit.c:768 #1 0x5650ef8eef88 in jit_object_close_impl /home/simark/src/binutils-gdb/gdb/jit.c:797 #2 0x7fbbda986278 in read_debug_info /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/jitreader.c:71 #3 0x5650ef8ef56b in jit_reader_try_read_symtab /home/simark/src/binutils-gdb/gdb/jit.c:850 #4 0x5650ef8effe3 in jit_register_code /home/simark/src/binutils-gdb/gdb/jit.c:948 #5 0x5650ef8f2c92 in jit_event_handler(gdbarch*) /home/simark/src/binutils-gdb/gdb/jit.c:1396 #6 0x5650ef0d137e in handle_jit_event /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470 [snip] 0x604000042eb8 is located 40 bytes inside of 48-byte region [0x604000042e90,0x604000042ec0) freed by thread T0 here: #0 0x7fbbe57376b0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122 #1 0x5650ef8f350b in xfree<gdb_block> /home/simark/src/binutils-gdb/gdb/gdbsupport/common-utils.h:62 #2 0x5650ef8eeca9 in finalize_symtab /home/simark/src/binutils-gdb/gdb/jit.c:769 #3 0x5650ef8eef88 in jit_object_close_impl /home/simark/src/binutils-gdb/gdb/jit.c:797 #4 0x7fbbda986278 in read_debug_info /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/jitreader.c:71 #5 0x5650ef8ef56b in jit_reader_try_read_symtab /home/simark/src/binutils-gdb/gdb/jit.c:850 #6 0x5650ef8effe3 in jit_register_code /home/simark/src/binutils-gdb/gdb/jit.c:948 #7 0x5650ef8f2c92 in jit_event_handler(gdbarch*) /home/simark/src/binutils-gdb/gdb/jit.c:1396 #8 0x5650ef0d137e in handle_jit_event /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470 [snip] previously allocated by thread T0 here: #0 0x7fbbe5737cd8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153 #1 0x5650eef662f3 in xcalloc /home/simark/src/binutils-gdb/gdb/alloc.c:100 #2 0x5650ef8f34ea in xcnew<gdb_block> /home/simark/src/binutils-gdb/gdb/gdbsupport/poison.h:122 #3 0x5650ef8ed467 in jit_block_open_impl /home/simark/src/binutils-gdb/gdb/jit.c:557 #4 0x7fbbda98620a in read_debug_info /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/jitreader.c:60 #5 0x5650ef8ef56b in jit_reader_try_read_symtab /home/simark/src/binutils-gdb/gdb/jit.c:850 #6 0x5650ef8effe3 in jit_register_code /home/simark/src/binutils-gdb/gdb/jit.c:948 #7 0x5650ef8f2c92 in jit_event_handler(gdbarch*) /home/simark/src/binutils-gdb/gdb/jit.c:1396 #8 0x5650ef0d137e in handle_jit_event /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470 [snip] gdb/ChangeLog: * jit.c (finalize_symtab): Set gdb_block_iter_tmp in loop. gdb/testsuite/ChangeLog: * gdb.base/jit-reader.exp (jit_reader_test): Rename jit_function_00 to jit_function_stack_mangle. * gdb.base/jithost.c (jit_function_t): Rename to... (jit_function_stack_mangle_t): ... this. (jit_function_add_t): New typedef. (jit_function_00_code): Rename to... (jit_function_stack_mangle_code): ... this, make static. (jit_function_add_code): New. (main): Generate "add" function and call it. Adjust to changes in jithost_abi. * gdb.base/jithost.h (struct jithost_abi_bounds): New. (struct jithost_abi) <begin, end>: Remove fields. <object, function_stack_mangle, function_add>: New fields. * gdb.base/jitreader.c (struct reader_state) <code_begin, code_end>: Remove fields. <func_stack_mangle>: New field. (read_debug_info): Adjust to renaming, create block for "add" function. (read_sp, unwind_frame, get_frame_id): Adjust to other changes. |
||
Simon Marchi
|
3a90f26667 |
Fix indentation in jit.c
Many places in this file use spaces only for indentation. Fix them to conform to GNU style. gdb/ChangeLog: * jit.c: Fix indentation, replace spaces with tabs where applicable. |
||
Tom Tromey
|
268e4f0914 |
Make the objfile destructor private
The idea behind this is that, in the long run, some code will need to be able to hold onto an objfile after it is unlinked from the program space. In particular, this is needed for some functionality to be moved to worker threads -- otherwise the objfile can be deleted while still in use. So, this makes ~objfile private, replacing it with an "unlink" method, making it more obvious which operation is intended at the calling points. gdb/ChangeLog 2019-12-12 Tom Tromey <tom@tromey.com> * symfile.c (syms_from_objfile_1): Use objfile_up. (syms_from_objfile_1, remove_symbol_file_command): Call unlink method. (reread_symbols): Use objfile_up. * solib.c (update_solib_list, reload_shared_libraries_1): Call unlink method. * objfiles.h (struct objfile) <~objfile>: Now private. <unlink>: New method. (struct objfile_deleter): New. (objfile_up): New typedef. * objfiles.c (objfile::unlink): New method. (free_objfile_separate_debug, free_all_objfiles) (objfile_purge_solibs): Use it. * jit.c (jit_unregister_code): Remove. (jit_inferior_exit_hook, jit_event_handler): Call unlink on objfile. * compile/compile-object-run.c (do_module_cleanup): Call unlink on objfile. * compile/compile-object-load.c (compile_object_load): Use objfile_up. Change-Id: I934bee70b26b8b24e1735828fb1e60fe8a05714f |
||
Tom Tromey
|
bda13cdcf0 |
Make the objfile constructor private
This changes the objfile constructor to be private, changing the callers to use a factory method. This isn't perhaps strictly needed for the goal of this series -- changing the container model of objfiles -- but is a nice symmetry. gdb/ChangeLog 2019-12-12 Tom Tromey <tom@tromey.com> * symfile.c (symbol_file_add_with_addrs): Use objfile::make. * objfiles.h (struct objfile): Make constructor private. <make>: New static method. * jit.c (jit_object_close_impl): Update. Change-Id: I42e07bc80a88cf3322ace94ffe869ae5788bcb29 |
||
Simon Marchi
|
7190276c52 |
Replace xmalloc/xfree with vector in jit.c
I'm currently studying that code and noticed this manual memory management, which could easily be replaced with a vector, so here it is. gdb/ChangeLog: * jit.c (jit_reader_try_read_symtab): Replace xmalloc/xfree with gdb::byte_vector. |
||
Mihails Strasuns
|
38b49e22b5 |
jit: minor improvement to debug logging
gdb/ChangeLog: 2019-11-28 Mihails Strasuns <mihails.strasuns@intel.com> * jit.c (jit_bfd_try_read_symtab): Fix printed function name in the debug output. * jit.c (jit_unregister_code): Add debug print to match `jit_register_code`. Change-Id: Ie66064f3aaa1c74facfc025c8d87f3a057869779 |