From 84acb35a5a97c28b24b1d61541dc1ee01a7d8a43 Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Wed, 1 Sep 2004 18:00:29 +0000 Subject: [PATCH] 2004-09-01 Jeff Johnston * observer.sh: Add struct so_list declaration. * Makefile.in: Add dependencies on observer.h for solib.c and breakpoint.c. * breakpoint.c (disable_breakpoints_in_unloaded_shlib): New function. (_initialize_breakpoint): Register disable_breakpoints_in_unloaded_shlib as an observer of the "solib unloaded" observation event. (re_enable_breakpoints_in_shlibs): For bp_shlib_disabled breakpoints, call decode_line_1 so unfound breakpoint errors are silent. * solib.c (update_solib_list): When a solib is discovered to have been unloaded by the program, notify all observers of the "solib unloaded" observation event. --- gdb/ChangeLog | 16 ++++++++++++++++ gdb/Makefile.in | 5 +++-- gdb/breakpoint.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- gdb/observer.sh | 1 + gdb/solib.c | 5 +++++ 5 files changed, 82 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 22ab390..a23a522 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2004-09-01 Jeff Johnston + + * observer.sh: Add struct so_list declaration. + * Makefile.in: Add dependencies on observer.h for solib.c and + breakpoint.c. + * breakpoint.c (disable_breakpoints_in_unloaded_shlib): New + function. + (_initialize_breakpoint): Register + disable_breakpoints_in_unloaded_shlib as an observer of the + "solib unloaded" observation event. + (re_enable_breakpoints_in_shlibs): For bp_shlib_disabled breakpoints, + call decode_line_1 so unfound breakpoint errors are silent. + * solib.c (update_solib_list): When a solib is discovered to have + been unloaded by the program, notify all observers of the + "solib unloaded" observation event. + 2004-09-01 Andrew Cagney * frame.c: Include "objfiles.h". diff --git a/gdb/Makefile.in b/gdb/Makefile.in index d2d7348..56caaad 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1719,7 +1719,7 @@ breakpoint.o: breakpoint.c $(defs_h) $(symtab_h) $(frame_h) $(breakpoint_h) \ $(gdb_string_h) $(demangle_h) $(annotate_h) $(symfile_h) \ $(objfiles_h) $(source_h) $(linespec_h) $(completer_h) $(gdb_h) \ $(ui_out_h) $(cli_script_h) $(gdb_assert_h) $(block_h) \ - $(gdb_events_h) + $(gdb_events_h) $(observer_h) $(solist_h) bsd-kvm.o: bsd-kvm.c $(defs_h) $(cli_cmds_h) $(command_h) $(frame_h) \ $(regcache_h) $(target_h) $(value_h) $(gdb_assert_h) $(readline_h) \ $(bsd_kvm_h) @@ -2451,7 +2451,8 @@ solib-aix5.o: solib-aix5.c $(defs_h) $(gdb_string_h) $(elf_external_h) \ solib.o: solib.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) $(symfile_h) \ $(objfiles_h) $(gdbcore_h) $(command_h) $(target_h) $(frame_h) \ $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) $(gdbcmd_h) \ - $(completer_h) $(filenames_h) $(exec_h) $(solist_h) $(readline_h) + $(completer_h) $(filenames_h) $(exec_h) $(solist_h) $(readline_h) \ + $(observer_h) solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \ $(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \ $(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 9858176..dae098d 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -49,6 +49,8 @@ #include "cli/cli-script.h" #include "gdb_assert.h" #include "block.h" +#include "solist.h" +#include "observer.h" #include "gdb-events.h" @@ -4388,6 +4390,46 @@ disable_breakpoints_in_shlibs (int silent) } } +/* Disable any breakpoints that are in in an unloaded shared library. Only + apply to enabled breakpoints, disabled ones can just stay disabled. */ + +void +disable_breakpoints_in_unloaded_shlib (struct so_list *solib) +{ + struct breakpoint *b; + int disabled_shlib_breaks = 0; + +#if defined (PC_SOLIB) + /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */ + ALL_BREAKPOINTS (b) + { + if ((b->loc->loc_type == bp_loc_hardware_breakpoint + || b->loc->loc_type == bp_loc_software_breakpoint) + && breakpoint_enabled (b) + && !b->loc->duplicate) + { + char *so_name = PC_SOLIB (b->loc->address); + if (so_name + && !strcmp (so_name, solib->so_name)) + { + b->enable_state = bp_shlib_disabled; + /* At this point, we cannot rely on remove_breakpoint + succeeding so we must mark the breakpoint as not inserted + to prevent future errors occurring in remove_breakpoints. */ + b->loc->inserted = 0; + if (!disabled_shlib_breaks) + { + target_terminal_ours_for_output (); + warning ("Temporarily disabling breakpoints for unloaded shared library \"%s\"", + so_name); + } + disabled_shlib_breaks = 1; + } + } + } +#endif +} + /* Try to reenable any breakpoints in shared libraries. */ void re_enable_breakpoints_in_shlibs (void) @@ -7100,6 +7142,8 @@ breakpoint_re_set_one (void *bint) struct breakpoint *b = (struct breakpoint *) bint; struct value *mark; int i; + int not_found; + int *not_found_ptr = NULL; struct symtabs_and_lines sals; char *s; enum enable_state save_enable; @@ -7150,11 +7194,19 @@ breakpoint_re_set_one (void *bint) save_enable = b->enable_state; if (b->enable_state != bp_shlib_disabled) b->enable_state = bp_disabled; + else + /* If resetting a shlib-disabled breakpoint, we don't want to + see an error message if it is not found since we will expect + this to occur until the shared library is finally reloaded. + We accomplish this by giving decode_line_1 a pointer to use + for silent notification that the symbol is not found. */ + not_found_ptr = ¬_found; set_language (b->language); input_radix = b->input_radix; s = b->addr_string; - sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL, NULL); + sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL, + not_found_ptr); for (i = 0; i < sals.nelts; i++) { resolve_sal_pc (&sals.sals[i]); @@ -7755,6 +7807,10 @@ _initialize_breakpoint (void) static struct cmd_list_element *breakpoint_show_cmdlist; struct cmd_list_element *c; +#ifdef SOLIB_ADD + observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib); +#endif + breakpoint_chain = 0; /* Don't bother to call set_breakpoint_count. $bpnum isn't useful before a breakpoint is set. */ diff --git a/gdb/observer.sh b/gdb/observer.sh index 2cc0e7f..b23f15e 100755 --- a/gdb/observer.sh +++ b/gdb/observer.sh @@ -52,6 +52,7 @@ case $lang in struct observer; struct bpstats; +struct so_list; EOF ;; esac diff --git a/gdb/solib.c b/gdb/solib.c index e722b98..8927568 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -42,6 +42,7 @@ #include "filenames.h" /* for DOSish file names */ #include "exec.h" #include "solist.h" +#include "observer.h" #include "readline/readline.h" /* external data declarations */ @@ -478,6 +479,10 @@ update_solib_list (int from_tty, struct target_ops *target) /* If it's not on the inferior's list, remove it from GDB's tables. */ else { + /* Notify any observer that the SO has been unloaded + before we remove it from the gdb tables. */ + observer_notify_solib_unloaded (gdb); + *gdb_link = gdb->next; /* Unless the user loaded it explicitly, free SO's objfile. */ -- 2.7.4