From c86cf029308edd78d12d1bb67a1d4ae1c14a9155 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Wed, 18 Feb 2009 07:28:34 +0000 Subject: [PATCH] * mi/mi-interp.c (mi_solib_loaded, mi_solib_unloaded): New. (mi_interpreter_init): Register the above. * solib.c (clear_solib): Notify solib unload. * breakpoint.c (disable_breakpoints_in_unloaded_shlib): Do not disable breakpoints on a.out targets. --- gdb/ChangeLog | 8 ++++++++ gdb/breakpoint.c | 8 ++++++++ gdb/doc/ChangeLog | 5 +++++ gdb/doc/gdb.texinfo | 16 ++++++++++++++++ gdb/mi/mi-interp.c | 30 ++++++++++++++++++++++++++++++ gdb/solib.c | 1 + gdb/testsuite/ChangeLog | 9 +++++++++ gdb/testsuite/gdb.mi/mi-nonstop.exp | 2 +- gdb/testsuite/gdb.mi/mi-nsintrall.exp | 2 +- gdb/testsuite/gdb.mi/mi-nsmoribund.exp | 2 +- gdb/testsuite/lib/mi-support.exp | 7 +++++-- 11 files changed, 85 insertions(+), 5 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f4b2e73..47912f7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2009-02-18 Vladimir Prus + + * mi/mi-interp.c (mi_solib_loaded, mi_solib_unloaded): New. + (mi_interpreter_init): Register the above. + * solib.c (clear_solib): Notify solib unload. + * breakpoint.c (disable_breakpoints_in_unloaded_shlib): Do not + disable breakpoints on a.out targets. + 2009-02-17 Vladimir Prus * observer.c (observer_test_first_notification_function) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 0caedec..8a7057b 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -4457,6 +4457,14 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib) struct bp_location *loc; int disabled_shlib_breaks = 0; + /* SunOS a.out shared libraries are always mapped, so do not + disable breakpoints; they will only be reported as unloaded + through clear_solib when GDB discards its shared library + list. See clear_solib for more information. */ + if (exec_bfd != NULL + && bfd_get_flavour (exec_bfd) == bfd_target_aout_flavour) + return; + ALL_BP_LOCATIONS (loc) { struct breakpoint *b = loc->owner; diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index ea22713..c4a3429 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2009-02-18 Vladimir Prus + + * gdb.texinfo (GDB/MI Async Records): Document the + =library-loaded and =library-unloaded notifications. + 2009-02-17 Vladimir Prus * observer.texi (test_notification): New observer. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 6aad520..ce959f5 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -19912,6 +19912,22 @@ We suggest that in response to this notification, front ends highlight the selected thread and cause subsequent commands to apply to that thread. +@item =library-loaded,... +Reports that a new library file was loaded by the program. This +notification has 4 fields---@var{id}, @var{target-name}, +@var{host-name}, and @var{symbols-loaded}. The @var{id} field is an +opaque identifier of the library. For remote debugging case, +@var{target-name} and @var{host-name} fields give the name of the +library file on the target, and on the host respectively. For native +debugging, both those fields have the same value. The +@var{symbols-loaded} field reports if the debug symbols for this +library are loaded. + +@item =library-unloaded,... +Reports that a library was unloaded by the program. This notification +has 3 fields---@var{id}, @var{target-name} and @var{host-name} with +the same meaning as for the @code{=library-loaded} notification + @end table @node GDB/MI Frame Information diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index 95dfdf4..65c1b4f 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -34,6 +34,7 @@ #include "mi-common.h" #include "observer.h" #include "gdbthread.h" +#include "solist.h" /* These are the interpreter setup, etc. functions for the MI interpreter */ static void mi_execute_command_wrapper (char *cmd); @@ -58,6 +59,8 @@ static void mi_thread_exit (struct thread_info *t); static void mi_new_inferior (int pid); static void mi_inferior_exit (int pid); static void mi_on_resume (ptid_t ptid); +static void mi_solib_loaded (struct so_list *solib); +static void mi_solib_unloaded (struct so_list *solib); static void * mi_interpreter_init (int top_level) @@ -86,6 +89,8 @@ mi_interpreter_init (int top_level) observer_attach_inferior_exit (mi_inferior_exit); observer_attach_normal_stop (mi_on_normal_stop); observer_attach_target_resumed (mi_on_resume); + observer_attach_solib_loaded (mi_solib_loaded); + observer_attach_solib_unloaded (mi_solib_unloaded); } return mi; @@ -408,6 +413,31 @@ mi_on_resume (ptid_t ptid) gdb_flush (raw_stdout); } +static void +mi_solib_loaded (struct so_list *solib) +{ + struct mi_interp *mi = top_level_interpreter_data (); + target_terminal_ours (); + fprintf_unfiltered (mi->event_channel, + "library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded=\"%d\"", + solib->so_original_name, solib->so_original_name, + solib->so_name, solib->symbols_loaded); + gdb_flush (mi->event_channel); +} + +static void +mi_solib_unloaded (struct so_list *solib) +{ + struct mi_interp *mi = top_level_interpreter_data (); + target_terminal_ours (); + fprintf_unfiltered (mi->event_channel, + "library-unloaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\"", + solib->so_original_name, solib->so_original_name, + solib->so_name); + gdb_flush (mi->event_channel); +} + + extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */ void diff --git a/gdb/solib.c b/gdb/solib.c index cce4f7f..5a28292 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -908,6 +908,7 @@ clear_solib (void) { struct so_list *so = so_list_head; so_list_head = so->next; + observer_notify_solib_unloaded (so); if (so->abfd) remove_target_sections (so->abfd); free_so (so); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 6c22a66..9b36fd1 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,14 @@ 2009-02-17 Vladimir Prus + * gdb.mi/mi-nonstop.exp (notifs): Adjust for library + notifications. + * gdb.mi/mi-nsintrall.exp (notifs): Likewise. + * gdb.mi/mi-nsmoribund.exp (notifs): Likewise. + * lib/mi-support.exp (library_loaded_re): New. + (mi_run_cmd, mi_send_resuming_command_raw): Adjust. + +2009-02-17 Vladimir Prus + * gdb.gdb/observer.exp: Use test_notification observer, not normal_stop, everywhere. (test_normal_stop_notifications): Rename to... diff --git a/gdb/testsuite/gdb.mi/mi-nonstop.exp b/gdb/testsuite/gdb.mi/mi-nonstop.exp index 2521ae5..08952b0 100644 --- a/gdb/testsuite/gdb.mi/mi-nonstop.exp +++ b/gdb/testsuite/gdb.mi/mi-nonstop.exp @@ -63,7 +63,7 @@ mi_gdb_test "200-break-insert -t main" ".*" set created "=thread-created,id=\"$decimal\"\r\n" set running "\\*running,thread-id=\"$decimal\"\r\n" -set notifs "($created)*($running)*" +set notifs "($created)*($running)*($library_loaded_re)*" # Note: presently, we skip this test on non-native targets, # so 'run' is OK. As soon as we start to run this on remote diff --git a/gdb/testsuite/gdb.mi/mi-nsintrall.exp b/gdb/testsuite/gdb.mi/mi-nsintrall.exp index b0d7b71..d34b08d 100644 --- a/gdb/testsuite/gdb.mi/mi-nsintrall.exp +++ b/gdb/testsuite/gdb.mi/mi-nsintrall.exp @@ -62,7 +62,7 @@ mi_gdb_test "200-break-insert -t main" ".*" set created "=thread-created,id=\"$decimal\"\r\n" set running "\\*running,thread-id=\"$decimal\"\r\n" -set notifs "($created)*($running)*" +set notifs "($created)*($running)*($library_loaded_re)*" # Note: presently, we skip this test on non-native targets, # so 'run' is OK. As soon as we start to run this on remote diff --git a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp index b836c5b..505fc84 100644 --- a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp +++ b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp @@ -62,7 +62,7 @@ mi_gdb_test "200-break-insert -t main" ".*" set created "=thread-created,id=\"$decimal\"\r\n" set running "\\*running,thread-id=\"$decimal\"\r\n" -set notifs "($created)*($running)*" +set notifs "($created)*($running)*($library_loaded_re)*" # Note: presently, we skip this test on non-native targets, # so 'run' is OK. As soon as we start to run this on remote diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index a2aa629..f62c240 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -31,6 +31,7 @@ global mi_inferior_tty_name set MIFLAGS "-i=mi" set thread_selected_re "=thread-selected,id=\"\[0-9+\]\"\r\n" +set library_loaded_re "=library-loaded\[^\n\]+\"\r\n" # # mi_gdb_exit -- exit the GDB, killing the target program if necessary @@ -778,6 +779,7 @@ proc mi_run_cmd {args} { } global mi_gdb_prompt global thread_selected_re + global library_loaded_re if [target_info exists gdb_init_command] { send_gdb "[target_info gdb_init_command]\n"; @@ -819,7 +821,7 @@ proc mi_run_cmd {args} { send_gdb "220-exec-run $args\n" gdb_expect { - -re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\",group-id=\"\[0-9\]+\"\r\n)*(${thread_selected_re})?${mi_gdb_prompt}" { + -re "220\\^running\r\n(\\*running,thread-id=\"\[^\"\]+\"\r\n|=thread-created,id=\"1\",group-id=\"\[0-9\]+\"\r\n)*(${library_loaded_re})*(${thread_selected_re})?${mi_gdb_prompt}" { } timeout { perror "Unable to start target" @@ -1435,10 +1437,11 @@ proc mi_send_resuming_command_raw {command test} { global mi_gdb_prompt global thread_selected_re + global library_loaded_re send_gdb "$command\n" gdb_expect { - -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n($thread_selected_re)?${mi_gdb_prompt}" { + -re "\\^running\r\n\\*running,thread-id=\"\[^\"\]+\"\r\n($library_loaded_re)*($thread_selected_re)?${mi_gdb_prompt}" { # Note that lack of 'pass' call here -- this works around limitation # in DejaGNU xfail mechanism. mi-until.exp has this: # -- 2.7.4