Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Vladimir Prus <vladimir@codesourcery.com>
To: gdb-patches@sources.redhat.com,  Nick Roberts <nickrob@snap.net.nz>
Subject: MI solib notification
Date: Fri, 30 Jan 2009 23:44:00 -0000	[thread overview]
Message-ID: <200901310010.46738.vladimir@codesourcery.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1124 bytes --]


This patch implements two new MI notifications,
=library-loaded and =library-unloaded. There's just one point of note --
identifications of shared libraries. In order for frontend to maintain
accurate list of shared libraries using notifications, there should be
a reliable way of matching unloaded library, as reported by =library-unloaded,
with a previously loaded library. Currently, GDB keeps two names associated
with a library, so_original_name which is reported by the target and so_name,
which is basically the name of the file where symbols are read from.

All internal comparisons of libraries for equality uses so_original_name, so
it makes sense that frontend use it too. However, it is technically possible
to load the same shared library twice, so ideally we use something more unique --
but this is extra work. So, MI notifications output three fields

	- id (documented as opaque)
	- target name
	- host name

presently, so_original_name is used for the first two, but in future, id might
become numeric, or it might look like libfoo.so@2. 

Comments? Is solib.c change OK? Are doc changes OK?

- Volodya



[-- Attachment #2: solib.diff --]
[-- Type: text/x-diff, Size: 7904 bytes --]

commit 8e9cd84e5a7b2302320b8a16ba7ba512057401b9
Author: Vladimir Prus <vladimir@codesourcery.com>
Date:   Fri Jan 30 20:50:50 2009 +0300

    Implement MI notification for library loading/unloading
    
    	gdb/doc/
    	* gdb.texinfo (GDB/MI Async Records): Document the
    	=library-loaded and =library-unloaded notifications.
    
    	gdb/
    	* mi/mi-interp.c (mi_solib_loaded, mi_solib_unloaded): New.
    	(mi_interpreter_init): Register the above.
    	* solib.c (clear_solib): Notify solib unload.
    
    	gdb/testsuite/
    	* 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.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index ffb29b4..d0e59a8 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19535,6 +19535,15 @@ 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,id="@var{id}",target-name="@var{target-name}",host-name="@var{host-name}",low-address="@var{low}",high-address="@var{high}",symbols-loaded="@var{loaded}"
+Reports that a new library file was loaded by the program.  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.
+
+@item =library-unloaded,id="@var{id}",target-name="@var{target-name}",host-name="@var{host-name}"
+Reports that a library was loaded by the program.
+
 @end table
 
 @node GDB/MI Frame Information
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index f530176..8e2b230 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;
@@ -379,6 +384,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\",low-address=\"0x%s\",high-address=\"0x%s\",symbols-loaded=\"%d\"", 
+		      solib->so_original_name, solib->so_original_name, 
+		      solib->so_name, 
+		      paddr (solib->addr_low), paddr (solib->addr_high), 
+		      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/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 a85e373..be9b530 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:
             #

             reply	other threads:[~2009-01-30 21:10 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-30 23:44 Vladimir Prus [this message]
     [not found] ` <utz7gzcmo.fsf@gnu.org>
2009-02-01 17:53   ` Daniel Jacobowitz
2009-02-01 18:22     ` Eli Zaretskii
2009-02-01 18:29       ` Daniel Jacobowitz
2009-02-17 19:09         ` Vladimir Prus
2009-02-17 19:45           ` Eli Zaretskii
2009-02-17 19:49             ` Vladimir Prus
2009-02-17 20:30               ` Eli Zaretskii
2009-02-17 21:45                 ` Vladimir Prus
2009-02-17 21:59                   ` Vladimir Prus
2009-02-18  7:31                     ` Eli Zaretskii
2009-02-18 10:19                       ` Vladimir Prus
2009-02-18 19:53                         ` Eli Zaretskii
2009-02-18 20:04                           ` Vladimir Prus
2009-02-18 22:28                             ` Eli Zaretskii
2009-02-18  4:24                   ` Eli Zaretskii
2009-02-17 21:37               ` Daniel Jacobowitz
2009-02-17 22:10               ` Pedro Alves
2009-02-18  2:01                 ` Pedro Alves
2009-02-01 18:04 ` Daniel Jacobowitz
2009-02-12  9:12   ` Vladimir Prus
2009-02-12 13:22     ` Daniel Jacobowitz
2009-02-12 15:02       ` Vladimir Prus
2009-02-12 15:13         ` Daniel Jacobowitz
2009-02-12 17:35           ` Tom Tromey
2009-02-12 18:02             ` Daniel Jacobowitz
2009-02-12 20:11               ` Tom Tromey
2009-02-12 20:17                 ` Vladimir Prus
2009-02-12 20:26                   ` Daniel Jacobowitz
2009-02-17 19:08                     ` Vladimir Prus
2009-02-12 18:06           ` Pedro Alves
2009-02-12 19:45             ` Pedro Alves
2009-02-12 19:56             ` Tom Tromey
2009-02-12 19:58               ` Daniel Jacobowitz
2009-02-13  2:22               ` Joel Brobecker
2009-02-01 18:47 ` Daniel Jacobowitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200901310010.46738.vladimir@codesourcery.com \
    --to=vladimir@codesourcery.com \
    --cc=gdb-patches@sources.redhat.com \
    --cc=nickrob@snap.net.nz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox