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]

[PATCH 3/3] Add -file-list-shared-libraries MI command


This change adds the MI equivalent for the "info sharedlibrary"
command. The command was already partially documented but ignored as
it was not implemented. The new MI command works similarly to the CLI
command, taking an optional regular expression as an argument and
outputting the library information.

I included a test for the new command in mi-solib.exp.

gdb/doc/ChangeLog:

        * gdb.texinfo (gdb/mi Symbol Query Commands): Document new MI
        command file-list-shared-libraries

gdb/ChangeLog:

        * mi/mi-cmd-file.c (mi_cmd_file_list_shared_libraries):
        New function definition.
        * mi/mi-cmds.c (mi_cmds): Add -file-list-shared-libraries command.
        * mi/mi-cmds.h (mi_cmd_file_list_shared_libraries):
        New function declaration.
        * solib.c (info_sharedlibrary_command): Replace for loop with
        ALL_SO_LIBS macro
        * solib.h (update_solib_list): New function declaration.
        * solist.h (ALL_SO_LIBS): New macro.

gdb/testsuite/ChangeLog:

        * gdb.mi/mi-solib.exp (test_file_list_shared_libraries):
        New procedure.

Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
---
 gdb/doc/gdb.texinfo               | 15 +++++++--
 gdb/mi/mi-cmd-file.c              | 67 +++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-cmds.c                  |  2 ++
 gdb/mi/mi-cmds.h                  |  1 +
 gdb/solib.c                       | 18 ++---------
 gdb/solib.h                       | 18 +++++++++++
 gdb/solist.h                      |  5 +++
 gdb/testsuite/gdb.mi/mi-solib.exp | 50 ++++++++++++++++++++---------
 8 files changed, 142 insertions(+), 34 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d1a5e7c..c6b2133 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -31401,26 +31401,35 @@ 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
 
 @subsubheading Synopsis
 
 @smallexample
- -file-list-shared-libraries
+ -file-list-shared-libraries [ @var{regexp} ]
 @end smallexample
 
 List the shared libraries in the program.
+With a regular expression @var{regexp}, only those libraries whose
+names match @var{regexp} are listed.
 
 @subsubheading @value{GDBN} Command
 
 The corresponding @value{GDBN} command is @samp{info shared}.
 
 @subsubheading Example
-N.A.
+@smallexample
+(gdb)
+-file-list-exec-source-files
+^done,shared-libraries=[
+@{from="0x72815989",to="0x728162c0",syms-read="1",name="/lib/libfoo.so"@},
+@{from="0x76ee48c0",to="0x76ee9160",syms-read="1",name="/lib/libbar.so"@}]
+(gdb)
+@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 310cd5b..eb8b361 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -25,6 +25,9 @@
 #include "source.h"
 #include "objfiles.h"
 #include "psymtab.h"
+#include "solib.h"
+#include "solist.h"
+#include "xregex.h"
 
 /* Return to the client the absolute path and line number of the 
    current file being executed.  */
@@ -108,3 +111,67 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
 
   ui_out_end (uiout, ui_out_type_list);
 }
+
+void
+mi_cmd_file_list_shared_libraries (char *command, char **argv, int argc)
+{
+  struct ui_out *uiout = current_uiout;
+  const char *pattern;
+  struct so_list *so = NULL;
+  struct gdbarch *gdbarch = target_gdbarch ();
+
+  switch (argc)
+    {
+    case 0:
+      pattern = NULL;
+      break;
+    case 1:
+      pattern = argv[0];
+      break;
+    default:
+      error (_("Usage: -file-list-shared-libraries [REGEXP]"));
+      break;
+    }
+
+  if (pattern != NULL)
+    {
+      char *re_err = re_comp (pattern);
+
+      if (re_err != NULL)
+	error (_("Invalid regexp: %s"), re_err);
+    }
+
+  update_solib_list (1);
+
+  /* Print the table header.  */
+  ui_out_begin (uiout, ui_out_type_list, "shared-libraries");
+
+  ALL_SO_LIBS (so)
+    {
+      if (so->so_name[0] == '\0')
+	continue;
+      if (pattern != NULL && !re_exec (so->so_name))
+	continue;
+
+      ui_out_begin (uiout, ui_out_type_tuple, NULL);
+
+      if (so->addr_high != 0)
+	{
+	  ui_out_field_core_addr (uiout, "from", gdbarch, so->addr_low);
+	  ui_out_field_core_addr (uiout, "to", gdbarch, so->addr_high);
+	}
+      else
+	{
+	  ui_out_field_skip (uiout, "from");
+	  ui_out_field_skip (uiout, "to");
+	}
+
+      ui_out_field_int (uiout, "syms-read", so->symbols_loaded ? 1 : 0);
+
+      ui_out_field_string (uiout, "name", so->so_name);
+
+      ui_out_end (uiout, ui_out_type_tuple);
+    }
+
+  ui_out_end (uiout, ui_out_type_list);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 4779832..18bb2a6 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -115,6 +115,8 @@ static struct mi_cmd mi_cmds[] =
 		 mi_cmd_file_list_exec_source_file),
   DEF_MI_CMD_MI ("file-list-exec-source-files",
 		 mi_cmd_file_list_exec_source_files),
+  DEF_MI_CMD_MI ("file-list-shared-libraries",
+		 mi_cmd_file_list_shared_libraries),
   DEF_MI_CMD_CLI ("file-symbol-file", "symbol-file", 1),
   DEF_MI_CMD_MI ("gdb-exit", mi_cmd_gdb_exit),
   DEF_MI_CMD_CLI_1 ("gdb-set", "set", 1,
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 69472a9..79241bb 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -70,6 +70,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 eefd6fb..fecf667 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -737,21 +737,7 @@ solib_used (const struct so_list *const known)
   return 0;
 }
 
-/* Synchronize GDB's shared object list with inferior's.
-
-   Extract the list of currently loaded shared objects from the
-   inferior, and compare it with the list of shared objects currently
-   in GDB's so_list_head list.  Edit so_list_head to bring it in sync
-   with the inferior's new list.
-
-   If we notice that the inferior has unloaded some shared objects,
-   free any symbolic info GDB had read about those shared objects.
-
-   Don't load symbolic info for any new shared objects; just add them
-   to the list, and leave their symbols_loaded flag clear.
-
-   If FROM_TTY is non-null, feel free to print messages about what
-   we're doing.  */
+/* See solib.h.  */
 
 void
 update_solib_list (int from_tty)
@@ -1096,7 +1082,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
 
   ui_out_table_body (uiout);
 
-  for (so = so_list_head; so; so = so->next)
+  ALL_SO_LIBS (so)
     {
       struct cleanup *lib_cleanup;
 
diff --git a/gdb/solib.h b/gdb/solib.h
index 75490b6..ee621ce 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -73,6 +73,24 @@ extern void no_shared_libraries (char *ignored, int from_tty);
 extern void set_solib_ops (struct gdbarch *gdbarch,
 			   const struct target_so_ops *new_ops);
 
+/* Synchronize GDB's shared object list with inferior's.
+
+   Extract the list of currently loaded shared objects from the
+   inferior, and compare it with the list of shared objects currently
+   in GDB's so_list_head list.  Edit so_list_head to bring it in sync
+   with the inferior's new list.
+
+   If we notice that the inferior has unloaded some shared objects,
+   free any symbolic info GDB had read about those shared objects.
+
+   Don't load symbolic info for any new shared objects; just add them
+   to the list, and leave their symbols_loaded flag clear.
+
+   If FROM_TTY is non-null, feel free to print messages about what
+   we're doing.  */
+
+extern void update_solib_list (int from_tty);
+
 /* Return non-zero if NAME is the libpthread shared library.  */
 
 extern int libpthread_name_p (const char *name);
diff --git a/gdb/solist.h b/gdb/solist.h
index 1bdfbaf..a46d23a 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -23,6 +23,11 @@
 /* For domain_enum domain.  */
 #include "symtab.h"
 
+#define ALL_SO_LIBS(so) \
+    for (so = current_program_space->so_list; \
+	 so; \
+	 so = so->next)
+
 /* Forward declaration for target specific link map information.  This
    struct is opaque to all but the target specific file.  */
 struct lm_info;
diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp
index 2227987..4c40ba4 100644
--- a/gdb/testsuite/gdb.mi/mi-solib.exp
+++ b/gdb/testsuite/gdb.mi/mi-solib.exp
@@ -48,27 +48,47 @@ if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != ""
 
 mi_delete_breakpoints
 mi_gdb_reinitialize_dir $srcdir/$subdir
-mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load ${binfile}
 
 mi_load_shlibs $binfile_lib
 
-mi_gdb_test "777-gdb-set stop-on-solib-events 1" "777\\^done" \
-    "set stop-on-solib-events"
+proc test_stop_on_solib_events {} {
+    mi_gdb_test "777-gdb-set stop-on-solib-events 1" "777\\^done" \
+	"set stop-on-solib-events"
 
-# We use "run" rather than "-exec-run" here in order to test that CLI
-# commands still cause the correct MI output to be generated.
-mi_run_with_cli
+    # We use "run" rather than "-exec-run" here in order to test that CLI
+    # commands still cause the correct MI output to be generated.
+    mi_run_with_cli
 
-# Also test that the CLI solib event note is output.
-set test "CLI prints solib event"
-gdb_expect {
-    -re "~\"Stopped due to shared library event \\(no libraries added or removed\\)\\\\n" {
-	pass "$test"
-    }
-    timeout {
-	fail "$test (timeout)"
+    # Also test that the CLI solib event note is output.
+    set test "CLI prints solib event"
+    gdb_expect {
+	-re "~\"Stopped due to shared library event \\(no libraries added or removed\\)\\\\n" {
+	    pass "$test"
+	}
+	timeout {
+	    fail "$test (timeout)"
+	}
     }
+
+    mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
+
+    # Unset solib events to avoid interfering with other tests.
+    mi_gdb_test "778-gdb-set stop-on-solib-events 0" "778\\^done" \
+	"unset stop-on-solib-events"
+}
+
+proc test_file_list_shared_libraries {} {
+    global libname
+    global binfile
+
+    mi_continue_to main
+
+    mi_gdb_test "222-file-list-shared-libraries" \
+	"222\\^done,shared-libraries=\\\[.*\{from=\".*\",to=\".*\",syms-read=\"1\",name=\".*${libname}.so\"\}.*]" \
+	"Getting a list of shared libraries."
 }
 
-mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
+test_stop_on_solib_events
+test_file_list_shared_libraries
+mi_gdb_exit
-- 
2.7.4


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