aboutsummaryrefslogtreecommitdiff
path: root/gdb/breakpoint.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2014-09-12 20:02:01 +0100
committerPedro Alves <palves@redhat.com>2014-09-12 20:02:01 +0100
commitf37f681c2bb884e74cd33340617a6d1a408d1a75 (patch)
treea11450c15c1662b085666340cf23cac5e81f0837 /gdb/breakpoint.c
parent75ac3a7f57ee93e9c59ca6e446ad14f860b9e7e5 (diff)
downloadgdb-f37f681c2bb884e74cd33340617a6d1a408d1a75.zip
gdb-f37f681c2bb884e74cd33340617a6d1a408d1a75.tar.gz
gdb-f37f681c2bb884e74cd33340617a6d1a408d1a75.tar.bz2
[IRIX] eliminate deprecated_insert_raw_breakpoint uses
The IRIX support wants to set a breakpoint to be hit when the startup phase is complete, which is where shared libraries have been mapped in. AFAIU, for most IRIX ports, that location is the entry point. For MIPS IRIX however, GDB needs to set a breakpoint earlier, in __dbx_link, as explained by: #ifdef SYS_syssgi /* On mips-irix, we need to stop the inferior early enough during the startup phase in order to be able to load the shared library symbols and insert the breakpoints that are located in these shared libraries. Stopping at the program entry point is not good enough because the -init code is executed before the execution reaches that point. So what we need to do is to insert a breakpoint in the runtime loader (rld), more precisely in __dbx_link(). This procedure is called by rld once all shared libraries have been mapped, but before the -init code is executed. Unfortuantely, this is not straightforward, as rld is not part of the executable we are running, and thus we need the inferior to run until rld itself has been mapped in memory. For this, we trace all syssgi() syscall exit events. Each time we detect such an event, we iterate over each text memory maps, get its associated fd, and scan the symbol table for __dbx_link(). When found, we know that rld has been mapped, and that we can insert the breakpoint at the symbol address. Once the dbx_link() breakpoint has been inserted, the syssgi() notifications are no longer necessary, so they should be canceled. */ proc_trace_syscalls_1 (pi, SYS_syssgi, PR_SYSEXIT, FLAG_SET, 0); #endif The loop in irix_solib_create_inferior_hook then runs until whichever breakpoint is hit first, the one set by solib-irix.c or the one set by procfs.c. Note the comment in disable_break talks about __dbx_init, but I think that's a typo for __dbx_link: - /* Note that it is possible that we have stopped at a location that - is different from the location where we inserted our breakpoint. - On mips-irix, we can actually land in __dbx_init(), so we should - not check the PC against our breakpoint address here. See procfs.c - for more details. */ This looks very much like referring to the loop in irix_solib_create_inferior_hook stopping at __dbx_link instead of at the entry point. What this patch does is convert these deprecated raw breakpoints to standard solib_event breakpoints. When the first solib-event breakpoint is hit, we delete all solib-event breakpoints. We do that in the so_ops->handle_event hook. This allows getting rid of the loop in irix_solib_create_inferior_hook completely, which should allow properly handling signals and other events in the early startup phase, like in SVR4. Built on x86_64 Fedora 20 with --enable-targets=all (builds solib-irix.c). Joel tested that with an earlier version of this patch "info shared" after starting a program gave the same list of shared libraries as before. gdb/ChangeLog: 2014-09-12 Pedro Alves <palves@redhat.com> * breakpoint.c (remove_solib_event_breakpoints_at_next_stop) (create_and_insert_solib_event_breakpoint): New functions. * breakpoint.h (create_and_insert_solib_event_breakpoint) (remove_solib_event_breakpoints_at_next_stop): New declarations. * procfs.c (dbx_link_bpt_addr, dbx_link_bpt): Delete globals. (remove_dbx_link_breakpoint): Delete function. (insert_dbx_link_bpt_in_file): Use create_and_insert_solib_event_breakpoint instead of deprecated_insert_raw_breakpoint. (procfs_wait): Don't check whether we hit __dbx_link here. (procfs_mourn_inferior): Don't delete the __dbx_link breakpoint here. * solib-irix.c (base_breakpoint): Delete global. (disable_break): Delete function. (enable_break): Use create_solib_event_breakpoint instead of deprecated_insert_raw_breakpoint. (irix_solib_handle_event): New function. (irix_solib_create_inferior_hook): Don't run the target or disable the mapping-complete breakpoint here. (_initialize_irix_solib): Install irix_solib_handle_event as so_ops->handle_event hook.
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r--gdb/breakpoint.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 683ed2b..f990d97 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7620,6 +7620,19 @@ remove_solib_event_breakpoints (void)
delete_breakpoint (b);
}
+/* See breakpoint.h. */
+
+void
+remove_solib_event_breakpoints_at_next_stop (void)
+{
+ struct breakpoint *b, *b_tmp;
+
+ ALL_BREAKPOINTS_SAFE (b, b_tmp)
+ if (b->type == bp_shlib_event
+ && b->loc->pspace == current_program_space)
+ b->disposition = disp_del_at_next_stop;
+}
+
struct breakpoint *
create_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
{
@@ -7631,6 +7644,24 @@ create_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
return b;
}
+/* See breakpoint.h. */
+
+struct breakpoint *
+create_and_insert_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
+{
+ struct breakpoint *b;
+
+ b = create_solib_event_breakpoint (gdbarch, address);
+ if (!breakpoints_always_inserted_mode ())
+ insert_breakpoint_locations ();
+ if (!b->loc->inserted)
+ {
+ delete_breakpoint (b);
+ return NULL;
+ }
+ return b;
+}
+
/* Disable any breakpoints that are on code in shared libraries. Only
apply to enabled breakpoints, disabled ones can just stay disabled. */