From 50c71eaf0e6a7026633818a76f14b6ab4efec73c Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Mon, 3 Nov 2008 14:01:27 +0000 Subject: [PATCH] * remote.c (remote_start_remote): If the solib list is global, fetch libraries and insert breakpoints after connecting. * infcmd.c (post_create_inferior): If the solist is shared between inferiors, no need to refetch it on every new inferior. (detach_command): If the shared library list is shared between inferiors, then don't clear it on every inferior detach. * gdbarch.sh (has_global_solist): New. * i386-dicos-tdep.c (i386_dicos_init_abi): Set gdbarch_has_global_solist. * target.c (target_pre_inferior): If the shared library list is shared between inferiors, then don't clear it here, neither invalidate the memory regions or clear the target description. (target_detach): If the shared library list is shared between inferiors, then don't remove breakpoints from the target here. (target_disconnect): Comment. * solib.c (update_solib_list): Check for null_ptid. * breakpoint.c (insert_breakpoints, update_global_location_list): If the shared library list is shared between inferiors, insert breakpoints even if there's no execution. (breakpoint_init_inferior): If the shared library list is shared between inferiors, don't delete breakpoints or mark them uninserted here. * gdbarch.c, gdbarch.h: Regenerate. --- gdb/ChangeLog | 27 +++++++++++++++++++++++++++ gdb/breakpoint.c | 17 +++++++++++++---- gdb/gdbarch.c | 23 +++++++++++++++++++++++ gdb/gdbarch.h | 6 ++++++ gdb/gdbarch.sh | 4 ++++ gdb/i386-dicos-tdep.c | 4 ++++ gdb/infcmd.c | 13 +++++++++++-- gdb/remote.c | 11 +++++++++++ gdb/solib.c | 2 +- gdb/target.c | 29 +++++++++++++++++++++-------- 10 files changed, 121 insertions(+), 15 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2b1ab7b..afec7c5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +2008-11-03 Pedro Alves + + * remote.c (remote_start_remote): If the solib list is global, + fetch libraries and insert breakpoints after connecting. + * infcmd.c (post_create_inferior): If the solist is shared between + inferiors, no need to refetch it on every new inferior. + (detach_command): If the shared library list is shared between + inferiors, then don't clear it on every inferior detach. + * gdbarch.sh (has_global_solist): New. + * i386-dicos-tdep.c (i386_dicos_init_abi): Set + gdbarch_has_global_solist. + * target.c (target_pre_inferior): If the shared library list is + shared between inferiors, then don't clear it here, neither + invalidate the memory regions or clear the target description. + (target_detach): If the shared library list is shared between + inferiors, then don't remove breakpoints from the target here. + (target_disconnect): Comment. + * solib.c (update_solib_list): Check for null_ptid. + * breakpoint.c (insert_breakpoints, update_global_location_list): + If the shared library list is shared between inferiors, insert + breakpoints even if there's no execution. + (breakpoint_init_inferior): If the shared library list is shared + between inferiors, don't delete breakpoints or mark them + uninserted here. + + * gdbarch.c, gdbarch.h: Regenerate. + 2008-10-31 Pedro Alves * inferior.h (inferior_ignoring_leading_exec_events): Delete diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 0076ff8..912d7ea 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1263,7 +1263,10 @@ insert_breakpoints (void) update_global_location_list (1); - if (!breakpoints_always_inserted_mode () && target_has_execution) + if (!breakpoints_always_inserted_mode () + && (target_has_execution + || (gdbarch_has_global_solist (target_gdbarch) + && target_supports_multi_process ()))) /* update_global_location_list does not insert breakpoints when always_inserted_mode is not enabled. Explicitly insert them now. */ @@ -1707,6 +1710,11 @@ breakpoint_init_inferior (enum inf_context context) struct bp_location *bpt; int ix; + /* If breakpoint locations are shared across processes, then there's + nothing to do. */ + if (gdbarch_has_global_solist (target_gdbarch)) + return; + ALL_BP_LOCATIONS (bpt) if (bpt->owner->enable_state != bp_permanent) bpt->inserted = 0; @@ -7259,9 +7267,10 @@ update_global_location_list (int should_insert) check_duplicates (b); } - if (breakpoints_always_inserted_mode () - && should_insert - && target_has_execution) + if (breakpoints_always_inserted_mode () && should_insert + && (target_has_execution + || (gdbarch_has_global_solist (target_gdbarch) + && target_supports_multi_process ()))) insert_breakpoint_locations (); } diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index aa9a455..dd6ad7f 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -240,6 +240,7 @@ struct gdbarch gdbarch_target_signal_from_host_ftype *target_signal_from_host; gdbarch_target_signal_to_host_ftype *target_signal_to_host; gdbarch_record_special_symbol_ftype *record_special_symbol; + int has_global_solist; }; @@ -371,6 +372,7 @@ struct gdbarch startup_gdbarch = default_target_signal_from_host, /* target_signal_from_host */ default_target_signal_to_host, /* target_signal_to_host */ 0, /* record_special_symbol */ + 0, /* has_global_solist */ /* startup_gdbarch() */ }; @@ -623,6 +625,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of target_signal_from_host, invalid_p == 0 */ /* Skip verify of target_signal_to_host, invalid_p == 0 */ /* Skip verify of record_special_symbol, has predicate */ + /* Skip verify of has_global_solist, invalid_p == 0 */ buf = ui_file_xstrdup (log, &dummy); make_cleanup (xfree, buf); if (strlen (buf) > 0) @@ -832,6 +835,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: get_longjmp_target = <0x%lx>\n", (long) gdbarch->get_longjmp_target); fprintf_unfiltered (file, + "gdbarch_dump: has_global_solist = %s\n", + plongest (gdbarch->has_global_solist)); + fprintf_unfiltered (file, "gdbarch_dump: have_nonsteppable_watchpoint = %s\n", plongest (gdbarch->have_nonsteppable_watchpoint)); fprintf_unfiltered (file, @@ -3237,6 +3243,23 @@ set_gdbarch_record_special_symbol (struct gdbarch *gdbarch, gdbarch->record_special_symbol = record_special_symbol; } +int +gdbarch_has_global_solist (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of has_global_solist, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_has_global_solist called\n"); + return gdbarch->has_global_solist; +} + +void +set_gdbarch_has_global_solist (struct gdbarch *gdbarch, + int has_global_solist) +{ + gdbarch->has_global_solist = has_global_solist; +} + /* Keep a registry of per-architecture data-pointers required by GDB modules. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index bc8298d..909db8c 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -811,6 +811,12 @@ typedef void (gdbarch_record_special_symbol_ftype) (struct gdbarch *gdbarch, str extern void gdbarch_record_special_symbol (struct gdbarch *gdbarch, struct objfile *objfile, asymbol *sym); extern void set_gdbarch_record_special_symbol (struct gdbarch *gdbarch, gdbarch_record_special_symbol_ftype *record_special_symbol); +/* True if the list of shared libraries is one and only for all + processes, as opposed to a list of shared libraries per inferior. */ + +extern int gdbarch_has_global_solist (struct gdbarch *gdbarch); +extern void set_gdbarch_has_global_solist (struct gdbarch *gdbarch, int has_global_solist); + extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 0c513a5..28983d3 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -707,6 +707,10 @@ m:int:target_signal_to_host:enum target_signal ts:ts::default_target_signal_to_h # Record architecture-specific information from the symbol table. M:void:record_special_symbol:struct objfile *objfile, asymbol *sym:objfile, sym + +# True if the list of shared libraries is one and only for all +# processes, as opposed to a list of shared libraries per inferior. +v:int:has_global_solist:::0:0::0 EOF } diff --git a/gdb/i386-dicos-tdep.c b/gdb/i386-dicos-tdep.c index 99c3d6f..665377c 100644 --- a/gdb/i386-dicos-tdep.c +++ b/gdb/i386-dicos-tdep.c @@ -49,6 +49,10 @@ i386_dicos_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_solib_ops (gdbarch, &solib_target_so_ops); + /* Every process, although has its own address space, sees the same + list of shared libraries. */ + set_gdbarch_has_global_solist (gdbarch, 1); + /* There's no (standard definition of) entry point or a guaranteed text location we could find with a symbol where to place the call dummy, so we put it on the stack. */ diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 607d2b3..63d8cca 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -398,7 +398,9 @@ post_create_inferior (struct target_ops *target, int from_tty) don't need to. */ target_find_description (); - if (exec_bfd) + /* If the solist is global across processes, there's no need to + refetch it here. */ + if (exec_bfd && !gdbarch_has_global_solist (target_gdbarch)) { /* Sometimes the platform-specific hook loads initial shared libraries, and sometimes it doesn't. Try to do so first, so @@ -410,7 +412,10 @@ post_create_inferior (struct target_ops *target, int from_tty) #else solib_add (NULL, from_tty, target, auto_solib_add); #endif + } + if (exec_bfd) + { /* Create the hooks to handle shared library load and unload events. */ #ifdef SOLIB_CREATE_INFERIOR_HOOK @@ -2341,7 +2346,11 @@ detach_command (char *args, int from_tty) { dont_repeat (); /* Not for the faint of heart. */ target_detach (args, from_tty); - no_shared_libraries (NULL, from_tty); + + /* If the solist is global across inferiors, don't clear it when we + detach from a single inferior. */ + if (!gdbarch_has_global_solist (target_gdbarch)) + no_shared_libraries (NULL, from_tty); /* If the current target interface claims there's still execution, then don't mess with threads of other processes. */ diff --git a/gdb/remote.c b/gdb/remote.c index 9f10c2a..a5589f6 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -2550,6 +2550,11 @@ remote_start_remote (struct ui_out *uiout, void *opaque) getpkt (&rs->buf, &rs->buf_size, 0); } + /* On OSs where the list of libraries is global to all + processes, we fetch them early. */ + if (gdbarch_has_global_solist (target_gdbarch)) + solib_add (NULL, args->from_tty, args->target, auto_solib_add); + /* Next, if the target can specify a description, read it. We do this before anything involving memory or registers. */ target_find_description (); @@ -2717,6 +2722,12 @@ remote_start_remote (struct ui_out *uiout, void *opaque) if (exec_bfd) /* No use without an exec file. */ remote_check_symbols (symfile_objfile); } + + /* If code is shared between processes, then breakpoints are global + too; Insert them now. */ + if (gdbarch_has_global_solist (target_gdbarch) + && breakpoints_always_inserted_mode ()) + insert_breakpoints (); } /* Open a connection to a remote debugger. diff --git a/gdb/solib.c b/gdb/solib.c index d40e70e..d04a907 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -510,7 +510,7 @@ update_solib_list (int from_tty, struct target_ops *target) /* We can reach here due to changing solib-search-path or the sysroot, before having any inferior. */ - if (target_has_execution) + if (target_has_execution && !ptid_equal (inferior_ptid, null_ptid)) { struct inferior *inf = current_inferior (); diff --git a/gdb/target.c b/gdb/target.c index 0976ad1..fa9a941 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1752,11 +1752,18 @@ target_pre_inferior (int from_tty) (gdb) attach 4712 Cannot access memory at address 0xdeadbeef */ - no_shared_libraries (NULL, from_tty); - invalidate_target_mem_regions (); + /* In some OSs, the shared library list is the same/global/shared + across inferiors. If code is shared between processes, so are + memory regions and features. */ + if (!gdbarch_has_global_solist (target_gdbarch)) + { + no_shared_libraries (NULL, from_tty); + + invalidate_target_mem_regions (); - target_clear_description (); + target_clear_description (); + } } /* This is to be called by the open routine before it does @@ -1790,9 +1797,14 @@ target_preopen (int from_tty) void target_detach (char *args, int from_tty) { - /* If we're in breakpoints-always-inserted mode, have to - remove them before detaching. */ - remove_breakpoints (); + if (gdbarch_has_global_solist (target_gdbarch)) + /* Don't remove global breakpoints here. They're removed on + disconnection from the target. */ + ; + else + /* If we're in breakpoints-always-inserted mode, have to remove + them before detaching. */ + remove_breakpoints (); (current_target.to_detach) (args, from_tty); } @@ -1802,8 +1814,9 @@ target_disconnect (char *args, int from_tty) { struct target_ops *t; - /* If we're in breakpoints-always-inserted mode, have to - remove them before disconnecting. */ + /* If we're in breakpoints-always-inserted mode or if breakpoints + are global across processes, we have to remove them before + disconnecting. */ remove_breakpoints (); for (t = current_target.beneath; t != NULL; t = t->beneath) -- 2.7.4