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-11-03 Pedro Alves <pedro@codesourcery.com>
+
+ * 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 <pedro@codesourcery.com>
* inferior.h (inferior_ignoring_leading_exec_events): Delete
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. */
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;
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 ();
}
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;
};
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() */
};
/* 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)
"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,
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. */
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);
# 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
}
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. */
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
#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
{
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. */
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 ();
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.
/* 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 ();
(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
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);
}
{
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)