This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: fix PR mi/8138


This needs at least a doc review.

This fixes PR 8138.  The bug is that there is no MI equivalent of "info
shared".

This patch fixes the bug in a reasonably straightforward way.  There is
a little ugliness in info_sharedlibrary_command, because the MI docs say
that new MI commands will always output lists, but this command was
emitting a table.

Built and regested on x86-64 (compile farm).
A new test case is included; this requires my previous patch.

Tom

2011-01-10  Tom Tromey  <tromey@redhat.com>

	PR mi/8138:
	* solib.h (info_sharedlibrary_command): Declare.
	* solib.c (info_sharedlibrary_command): No longer 'static'.
	Handle MI output.
	* mi/mi-cmds.c (mi_cmds): Add "file-list-shared-libraries" entry.
	* mi/mi-cmd-file.c (mi_cmd_file_list_shared_libraries): New
	function.
	* mi/mi-cmds.h (mi_cmd_file_list_shared_libraries): Declare.

2011-01-10  Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (GDB/MI File Commands): Document
	-file-list-shared-libraries.

2011-01-10  Tom Tromey  <tromey@redhat.com>

	* gdb.mi/mi-solib.exp: Add test for -file-list-shared-libraries.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7f8c785..e3a59cd 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -28847,7 +28847,7 @@ The @value{GDBN} equivalent is @samp{info sources}.
 (gdb)
 @end smallexample
 
-@ignore
+
 @subheading The @code{-file-list-shared-libraries} Command
 @findex -file-list-shared-libraries
 
@@ -28859,14 +28859,41 @@ The @value{GDBN} equivalent is @samp{info sources}.
 
 List the shared libraries in the program.
 
+@subsubheading Result
+
+The result is a table of libraries.  The following attributes are
+defined for a given library:
+
+@table @samp
+@item from
+@itemx to
+These items, if provided, are a range of addresses belonging to this
+shared library.
+
+@item syms-read
+This indicates whether debugging information has been read for this
+library.  This is either @samp{0}, meaning that debugging information
+for this library has not been read; @samp{1}, meaning that the library
+does not have debugging information; or @samp{2}, meaning that the
+debugging information exists and has been read.
+
+@item name
+The name of the library.
+@end table
+
 @subsubheading @value{GDBN} Command
 
 The corresponding @value{GDBN} command is @samp{info shared}.
 
 @subsubheading Example
-N.A.
+@smallexample
+(gdb)
+-file-list-shared-libraries
+^done,sharedlibs=[lib=[from="0x00111360",to="0x00111498",syms-read="2",name="/lib/libexample.so"]]
+@end smallexample
 
 
+@ignore
 @subheading The @code{-file-list-symbol-files} Command
 @findex -file-list-symbol-files
 
diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c
index e575012..b7d0030 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -26,6 +26,7 @@
 #include "source.h"
 #include "objfiles.h"
 #include "psymtab.h"
+#include "solib.h"
 
 /* Return to the client the absolute path and line number of the 
    current file being executed. */
@@ -109,3 +110,14 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
 
   ui_out_end (uiout, ui_out_type_list);
 }
+
+/* Implementation of the -file-list-shared-libraries command.  */
+
+void
+mi_cmd_file_list_shared_libraries (char *command, char **argv, int argc)
+{
+  if (!mi_valid_noargs ("mi_cmd_file_list_shared_libraries", argc, argv))
+    error (_("mi_cmd_file_list_shared_libraries: Usage: No args"));
+
+  info_sharedlibrary_command (NULL, 0);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 0b32db0..3e6da2e 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -82,6 +82,8 @@ struct mi_cmd mi_cmds[] =
     mi_cmd_file_list_exec_source_file},
   { "file-list-exec-source-files", { NULL, 0 },
     mi_cmd_file_list_exec_source_files },
+  { "file-list-shared-libraries", { NULL, 0 },
+    mi_cmd_file_list_shared_libraries },
   { "file-symbol-file", { "symbol-file", 1 }, NULL },
   { "gdb-exit", { NULL, 0 }, mi_cmd_gdb_exit},
   { "gdb-set", { "set", 1 }, NULL },
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 18b4ad7..1cb5556 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -68,6 +68,7 @@ extern mi_cmd_argv_ftype mi_cmd_exec_step;
 extern mi_cmd_argv_ftype mi_cmd_exec_step_instruction;
 extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_file;
 extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_files;
+extern mi_cmd_argv_ftype mi_cmd_file_list_shared_libraries;
 extern mi_cmd_argv_ftype mi_cmd_gdb_exit;
 extern mi_cmd_argv_ftype mi_cmd_inferior_tty_set;
 extern mi_cmd_argv_ftype mi_cmd_inferior_tty_show;
diff --git a/gdb/solib.c b/gdb/solib.c
index 8fe35e5..975e9fb 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1002,14 +1002,14 @@ solib_add (char *pattern, int from_tty,
    print them all.
  */
 
-static void
+void
 info_sharedlibrary_command (char *pattern, int from_tty)
 {
   struct so_list *so = NULL;	/* link map state variable */
   int so_missing_debug_info = 0;
   int addr_width;
-  int nr_libs;
-  struct cleanup *table_cleanup;
+  int nr_libs = 0;
+  struct cleanup *content_cleanup;
   struct gdbarch *gdbarch = target_gdbarch;
 
   if (pattern)
@@ -1025,42 +1025,56 @@ info_sharedlibrary_command (char *pattern, int from_tty)
 
   update_solib_list (from_tty, 0);
 
-  /* make_cleanup_ui_out_table_begin_end needs to know the number of
-     rows, so we need to make two passes over the libs.  */
-
-  for (nr_libs = 0, so = so_list_head; so; so = so->next)
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      /* Output a simple list for MI.  */
+      content_cleanup = make_cleanup_ui_out_list_begin_end (uiout,
+							    "sharedlibs");
+    }
+  else
     {
-      if (so->so_name[0])
+      /* make_cleanup_ui_out_table_begin_end needs to know the number
+	 of rows, so we need to make two passes over the libs.  */
+
+      for (nr_libs = 0, so = so_list_head; so; so = so->next)
 	{
-	  if (pattern && ! re_exec (so->so_name))
-	    continue;
-	  ++nr_libs;
+	  if (so->so_name[0])
+	    {
+	      if (pattern && ! re_exec (so->so_name))
+		continue;
+	      ++nr_libs;
+	    }
 	}
-    }
 
-  table_cleanup =
-    make_cleanup_ui_out_table_begin_end (uiout, 4, nr_libs,
-					 "SharedLibraryTable");
+      content_cleanup =
+	make_cleanup_ui_out_table_begin_end (uiout, 4, nr_libs,
+					     "SharedLibraryTable");
 
-  /* The "- 1" is because ui_out adds one space between columns.  */
-  ui_out_table_header (uiout, addr_width - 1, ui_left, "from", "From");
-  ui_out_table_header (uiout, addr_width - 1, ui_left, "to", "To");
-  ui_out_table_header (uiout, 12 - 1, ui_left, "syms-read", "Syms Read");
-  ui_out_table_header (uiout, 0, ui_noalign,
-		       "name", "Shared Object Library");
+      /* The "- 1" is because ui_out adds one space between columns.  */
+      ui_out_table_header (uiout, addr_width - 1, ui_left, "from", "From");
+      ui_out_table_header (uiout, addr_width - 1, ui_left, "to", "To");
+      ui_out_table_header (uiout, 12 - 1, ui_left, "syms-read", "Syms Read");
+      ui_out_table_header (uiout, 0, ui_noalign,
+			   "name", "Shared Object Library");
 
-  ui_out_table_body (uiout);
+      ui_out_table_body (uiout);
+    }
 
   for (so = so_list_head; so; so = so->next)
     {
       struct cleanup *lib_cleanup;
+      static const char *read_names[] = { "No", "Yes (*)", "Yes" };
+      int read_kind;
 
       if (! so->so_name[0])
 	continue;
       if (pattern && ! re_exec (so->so_name))
 	continue;
 
-      lib_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "lib");
+      if (ui_out_is_mi_like_p (uiout))
+	lib_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "lib");
+      else
+	lib_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "lib");
 
       if (so->addr_high != 0)
 	{
@@ -1073,16 +1087,28 @@ info_sharedlibrary_command (char *pattern, int from_tty)
 	  ui_out_field_skip (uiout, "to");
 	}
 
-      if (! ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
+      /* We check the top-level interpreter's ui-out object here for
+	 historical compatibility: older versions of gdb did not
+	 expose this function to MI, and so clients were forced to
+	 parse the "info shared" output.  The additional check for the
+	 current ui-out object lets us avoid this backward
+	 compatibility in the case of a "native" MI request.  */
+      if ((ui_out_is_mi_like_p (uiout)
+	   || ! ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
 	  && so->symbols_loaded
 	  && !objfile_has_symbols (so->objfile))
 	{
 	  so_missing_debug_info = 1;
+	  read_kind = 1;
 	  ui_out_field_string (uiout, "syms-read", "Yes (*)");
 	}
       else
-	ui_out_field_string (uiout, "syms-read", 
-			     so->symbols_loaded ? "Yes" : "No");
+	read_kind = so->symbols_loaded ? 2 : 0;
+
+      if (ui_out_is_mi_like_p (uiout))
+	ui_out_field_int (uiout, "syms-read", read_kind);
+      else
+	ui_out_field_string (uiout, "syms-read", read_names[read_kind]);
 
       ui_out_field_string (uiout, "name", so->so_name);
 
@@ -1091,9 +1117,13 @@ info_sharedlibrary_command (char *pattern, int from_tty)
       do_cleanups (lib_cleanup);
     }
 
-  do_cleanups (table_cleanup);
+  do_cleanups (content_cleanup);
 
-  if (nr_libs == 0)
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      /* Nothing.  */
+    }
+  else if (nr_libs == 0)
     {
       if (pattern)
 	ui_out_message (uiout, 0,
diff --git a/gdb/solib.h b/gdb/solib.h
index bce21e5..c121d3a 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -78,4 +78,8 @@ extern void set_solib_ops (struct gdbarch *gdbarch,
 
 extern int libpthread_name_p (const char *name);
 
+/* Print information about shared libraries.  */
+
+extern void info_sharedlibrary_command (char *pattern, int from_tty);
+
 #endif /* SOLIB_H */
diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp
index ec2623e..7a94db5 100644
--- a/gdb/testsuite/gdb.mi/mi-solib.exp
+++ b/gdb/testsuite/gdb.mi/mi-solib.exp
@@ -50,6 +50,10 @@ if [mi_gdb_start] {
 
 mi_gdb_load ${binfile}
 
+mi_gdb_test "200-break-insert -t main" \
+    "200\\^done,bkpt=\{.*\}" \
+    "set temporary breakpoint at main for solib test"
+
 mi_run_cmd
 
 set libtest "*${libname}*"
@@ -68,7 +72,7 @@ gdb_expect {
     -re "(${thread_selected_re})?${mi_gdb_prompt}" {
     }
     timeout {
-	perror "Unable to start target"
+	perror "timeout waiting for =library-loaded"
 	return -1
     }
 }
@@ -78,3 +82,7 @@ if {$lib_found} {
 } else {
     fail "checking library load $libname"
 }
+
+mi_gdb_test "201-file-list-shared-libraries" \
+    "201\\^done,.*name=.*$libname.*\]\]" \
+    "test -file-list-shared-libraries"
-- 
1.7.2.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]