public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2/3] Add a better diagnostic message in mi_gdb_test
  2016-09-12 20:28 [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
@ 2016-09-12 20:28 ` Marc-Andre Laperle
  2016-10-20  4:24   ` Simon Marchi
  2016-11-23 13:03   ` Pedro Alves
  2016-09-12 20:28 ` [PATCH 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 26+ messages in thread
From: Marc-Andre Laperle @ 2016-09-12 20:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

When using mi_gdb_test, if it fails because of the presence of
unexpected output, the error message is only the message passed as
the argument with no indication that there was an unexpected output.
This change adds an additional text to the failure message to
indicate that there was an unexpected output.

gdb/testsuite/ChangeLog:

        * lib/mi-support.exp (mi_gdb_test): Add additional message
        for unexpected output.

Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
---
 gdb/testsuite/lib/mi-support.exp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 7c2bb3e..25995cf 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -824,7 +824,7 @@ proc mi_gdb_test { args } {
 	}
 	 -re ".*$mi_gdb_prompt\[ \]*$" {
 	    if ![string match "" $message] then {
-		fail "$message"
+		fail "$message (unexpected output)"
 	    }
 	    set result 1
 	}
-- 
2.7.4

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 3/3] Add -file-list-shared-libraries MI command
  2016-09-12 20:28 [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
  2016-09-12 20:28 ` [PATCH 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle
@ 2016-09-12 20:28 ` Marc-Andre Laperle
  2016-10-14 21:20   ` Marc-André Laperle
                     ` (2 more replies)
  2016-10-20  4:20 ` [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Simon Marchi
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 26+ messages in thread
From: Marc-Andre Laperle @ 2016-09-12 20:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

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

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list
@ 2016-09-12 20:28 Marc-Andre Laperle
  2016-09-12 20:28 ` [PATCH 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle
                   ` (4 more replies)
  0 siblings, 5 replies; 26+ messages in thread
From: Marc-Andre Laperle @ 2016-09-12 20:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

The target parameter in both solib_add and update_solib_list
functions is not used anymore and as not been used for a while. This
change removes the parameter to clean up the code a little bit.

gdb/ChangeLog:

        * infcmd.c (post_create_inferior): Remove unused argument in
        call to solib_add.
        * remote.c (remote_start_remote): Likewise.
        * solib-frv.c (frv_fetch_objfile_link_map): Likewise.
        * solib-svr4.c: (svr4_fetch_objfile_link_map): Likewise.
        (enable_break): Likewise.
        * solib.c (update_solib_list): Remove unused target argument
        and its documentation.
        (solib_add): Remove unused target argument.  Remove unused
        argument in call to update_solib_list.
        (info_sharedlibrary_command): Remove unused argument in call
        to update_solib_list.
        (sharedlibrary_command): Remove unused argument in call to
        solib_add.
        (handle_solib_event): Likewise.
        (reload_shared_libraries): Likewise.
        * solib.h (solib_add): Remove unused target argument.

Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
---
 gdb/infcmd.c     |  2 +-
 gdb/remote.c     |  2 +-
 gdb/solib-frv.c  |  2 +-
 gdb/solib-svr4.c |  6 +++---
 gdb/solib.c      | 28 ++++++++++------------------
 gdb/solib.h      |  2 +-
 6 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 44a1fd1..b0daadb 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -458,7 +458,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
 	  /* If the solist is global across processes, there's no need to
 	     refetch it here.  */
 	  if (!gdbarch_has_global_solist (target_gdbarch ()))
-	    solib_add (NULL, 0, target, auto_solib_add);
+	    solib_add (NULL, 0, auto_solib_add);
 	}
     }
 
diff --git a/gdb/remote.c b/gdb/remote.c
index 13258b9e..428b3cc 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -4097,7 +4097,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
   /* On OSs where the list of libraries is global to all
      processes, we fetch them early.  */
   if (gdbarch_has_global_solist (target_gdbarch ()))
-    solib_add (NULL, from_tty, target, auto_solib_add);
+    solib_add (NULL, from_tty, auto_solib_add);
 
   if (target_is_non_stop_p ())
     {
diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
index 56ccb88..d6b2007 100644
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -1145,7 +1145,7 @@ frv_fetch_objfile_link_map (struct objfile *objfile)
 
   /* Cause frv_current_sos() to be run if it hasn't been already.  */
   if (main_lm_addr == 0)
-    solib_add (0, 0, 0, 1);
+    solib_add (0, 0, 1);
 
   /* frv_current_sos() will set main_lm_addr for the main executable.  */
   if (objfile == symfile_objfile)
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index fe36d45..2e2de5f 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1614,7 +1614,7 @@ svr4_fetch_objfile_link_map (struct objfile *objfile)
 
   /* Cause svr4_current_sos() to be run if it hasn't been already.  */
   if (info->main_lm_addr == 0)
-    solib_add (NULL, 0, &current_target, auto_solib_add);
+    solib_add (NULL, 0, auto_solib_add);
 
   /* svr4_current_sos() will set main_lm_addr for the main executable.  */
   if (objfile == symfile_objfile)
@@ -2273,7 +2273,7 @@ enable_break (struct svr4_info *info, int from_tty)
      mean r_brk has already been relocated.  Assume the dynamic linker
      is the object containing r_brk.  */
 
-  solib_add (NULL, from_tty, &current_target, auto_solib_add);
+  solib_add (NULL, from_tty, auto_solib_add);
   sym_addr = 0;
   if (info->debug_base && solib_svr4_r_map (info) != 0)
     sym_addr = solib_svr4_r_brk (info);
@@ -2451,7 +2451,7 @@ enable_break (struct svr4_info *info, int from_tty)
 	  info->debug_loader_name = xstrdup (interp_name);
 	  info->debug_loader_offset_p = 1;
 	  info->debug_loader_offset = load_addr;
-	  solib_add (NULL, from_tty, &current_target, auto_solib_add);
+	  solib_add (NULL, from_tty, auto_solib_add);
 	}
 
       /* Record the relocated start and end address of the dynamic linker
diff --git a/gdb/solib.c b/gdb/solib.c
index 2235505..eefd6fb 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -751,17 +751,10 @@ solib_used (const struct so_list *const known)
    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.
+   we're doing.  */
 
-   If TARGET is non-null, add the sections of all new shared objects
-   to TARGET's section table.  Note that this doesn't remove any
-   sections for shared objects that have been unloaded, and it
-   doesn't check to see if the new shared objects are already present in
-   the section table.  But we only use this for core files and
-   processes we've just attached to, so that's okay.  */
-
-static void
-update_solib_list (int from_tty, struct target_ops *target)
+void
+update_solib_list (int from_tty)
 {
   const struct target_so_ops *ops = solib_ops (target_gdbarch ());
   struct so_list *inferior = ops->current_sos();
@@ -962,11 +955,10 @@ libpthread_solib_p (struct so_list *so)
    If READSYMS is 0, defer reading symbolic information until later
    but still do any needed low level processing.
 
-   FROM_TTY and TARGET are as described for update_solib_list, above.  */
+   FROM_TTY is described for update_solib_list, above.  */
 
 void
-solib_add (const char *pattern, int from_tty,
-	   struct target_ops *target, int readsyms)
+solib_add (const char *pattern, int from_tty, int readsyms)
 {
   struct so_list *gdb;
 
@@ -991,7 +983,7 @@ solib_add (const char *pattern, int from_tty,
 	error (_("Invalid regexp: %s"), re_err);
     }
 
-  update_solib_list (from_tty, target);
+  update_solib_list (from_tty);
 
   /* Walk the list of currently loaded shared libraries, and read
      symbols for any that match the pattern --- or any whose symbols
@@ -1076,7 +1068,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
   /* "0x", a little whitespace, and two hex digits per byte of pointers.  */
   addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
 
-  update_solib_list (from_tty, 0);
+  update_solib_list (from_tty);
 
   /* make_cleanup_ui_out_table_begin_end needs to know the number of
      rows, so we need to make two passes over the libs.  */
@@ -1293,7 +1285,7 @@ static void
 sharedlibrary_command (char *args, int from_tty)
 {
   dont_repeat ();
-  solib_add (args, from_tty, (struct target_ops *) 0, 1);
+  solib_add (args, from_tty, 1);
 }
 
 /* Implements the command "nosharedlibrary", which discards symbols
@@ -1340,7 +1332,7 @@ handle_solib_event (void)
      be adding them automatically.  Switch terminal for any messages
      produced by breakpoint_re_set.  */
   target_terminal_ours_for_output ();
-  solib_add (NULL, 0, &current_target, auto_solib_add);
+  solib_add (NULL, 0, auto_solib_add);
   target_terminal_inferior ();
 }
 
@@ -1458,7 +1450,7 @@ reload_shared_libraries (char *ignored, int from_tty,
      removed.  Call it only after the solib target has been initialized by
      solib_create_inferior_hook.  */
 
-  solib_add (NULL, 0, NULL, auto_solib_add);
+  solib_add (NULL, 0, auto_solib_add);
 
   breakpoint_re_set ();
 
diff --git a/gdb/solib.h b/gdb/solib.h
index 00fd6cb..75490b6 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -33,7 +33,7 @@ extern void clear_solib (void);
 
 /* Called to add symbols from a shared library to gdb's symbol table.  */
 
-extern void solib_add (const char *, int, struct target_ops *, int);
+extern void solib_add (const char *, int, int);
 extern int solib_read_symbols (struct so_list *, int);
 
 /* Function to be called when the inferior starts up, to discover the
-- 
2.7.4

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] Add -file-list-shared-libraries MI command
  2016-09-12 20:28 ` [PATCH 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
@ 2016-10-14 21:20   ` Marc-André Laperle
  2016-10-20  5:05   ` Simon Marchi
  2016-11-23 13:06   ` Pedro Alves
  2 siblings, 0 replies; 26+ messages in thread
From: Marc-André Laperle @ 2016-10-14 21:20 UTC (permalink / raw)
  To: gdb-patches


Ping.






From: Marc-André Laperle
Sent: Monday, September 12, 2016 4:27 PM
To: gdb-patches@sourceware.org
Cc: Marc-André Laperle
Subject: [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

    

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list
  2016-09-12 20:28 [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
  2016-09-12 20:28 ` [PATCH 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle
  2016-09-12 20:28 ` [PATCH 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
@ 2016-10-20  4:20 ` Simon Marchi
  2016-11-23 13:03 ` Pedro Alves
  2017-02-03 17:17 ` [PATCH v2 0/3] Shared libraries MI command Marc-Andre Laperle
  4 siblings, 0 replies; 26+ messages in thread
From: Simon Marchi @ 2016-10-20  4:20 UTC (permalink / raw)
  To: Marc-Andre Laperle; +Cc: gdb-patches

On 2016-09-12 16:27, Marc-Andre Laperle wrote:
> The target parameter in both solib_add and update_solib_list
> functions is not used anymore and as not been used for a while. This
> change removes the parameter to clean up the code a little bit.
> 
> gdb/ChangeLog:
> 
>         * infcmd.c (post_create_inferior): Remove unused argument in
>         call to solib_add.
>         * remote.c (remote_start_remote): Likewise.
>         * solib-frv.c (frv_fetch_objfile_link_map): Likewise.
>         * solib-svr4.c: (svr4_fetch_objfile_link_map): Likewise.
>         (enable_break): Likewise.
>         * solib.c (update_solib_list): Remove unused target argument
>         and its documentation.
>         (solib_add): Remove unused target argument.  Remove unused
>         argument in call to update_solib_list.
>         (info_sharedlibrary_command): Remove unused argument in call
>         to update_solib_list.
>         (sharedlibrary_command): Remove unused argument in call to
>         solib_add.
>         (handle_solib_event): Likewise.
>         (reload_shared_libraries): Likewise.
>         * solib.h (solib_add): Remove unused target argument.
> 
> Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>

This patch looks good to me.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/3] Add a better diagnostic message in mi_gdb_test
  2016-09-12 20:28 ` [PATCH 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle
@ 2016-10-20  4:24   ` Simon Marchi
  2016-11-23 13:03   ` Pedro Alves
  1 sibling, 0 replies; 26+ messages in thread
From: Simon Marchi @ 2016-10-20  4:24 UTC (permalink / raw)
  To: Marc-Andre Laperle; +Cc: gdb-patches

On 2016-09-12 16:27, Marc-Andre Laperle wrote:
> When using mi_gdb_test, if it fails because of the presence of
> unexpected output, the error message is only the message passed as
> the argument with no indication that there was an unexpected output.
> This change adds an additional text to the failure message to
> indicate that there was an unexpected output.
> 
> gdb/testsuite/ChangeLog:
> 
>         * lib/mi-support.exp (mi_gdb_test): Add additional message
>         for unexpected output.
> 
> Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
> ---
>  gdb/testsuite/lib/mi-support.exp | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gdb/testsuite/lib/mi-support.exp 
> b/gdb/testsuite/lib/mi-support.exp
> index 7c2bb3e..25995cf 100644
> --- a/gdb/testsuite/lib/mi-support.exp
> +++ b/gdb/testsuite/lib/mi-support.exp
> @@ -824,7 +824,7 @@ proc mi_gdb_test { args } {
>  	}
>  	 -re ".*$mi_gdb_prompt\[ \]*$" {
>  	    if ![string match "" $message] then {
> -		fail "$message"
> +		fail "$message (unexpected output)"
>  	    }
>  	    set result 1
>  	}

Looks good to me, more details do not hurt.  If it wasn't clear for you, 
it probably wasn't for some other people too.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] Add -file-list-shared-libraries MI command
  2016-09-12 20:28 ` [PATCH 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
  2016-10-14 21:20   ` Marc-André Laperle
@ 2016-10-20  5:05   ` Simon Marchi
  2016-11-23 13:06   ` Pedro Alves
  2 siblings, 0 replies; 26+ messages in thread
From: Simon Marchi @ 2016-10-20  5:05 UTC (permalink / raw)
  To: Marc-Andre Laperle; +Cc: gdb-patches

The patch looks good to me in general.  I wrote a few minor comments 
inline.

On 2016-09-12 16:27, Marc-Andre Laperle wrote:
> @@ -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);

const ?

> +
> +      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");

It's not a big deal, but you could use 
make_cleanup_ui_out_list_begin_end, which avoids accidentally forgetting 
the corresponding ui_out_end.

> +
> +  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);

Same here, but with make_cleanup_ui_out_tuple_begin_end.

> +      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");
> +	}

You might be able to just remove the else.  I think ui_out_field_skip is 
only relevant for tables (which was used in the code that you took 
inspiration from), since you need to explicitly tell if you want to skip 
a table cell.  For tuples, if you want to omit a field, you just don't 
emit it.

> 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.  */

I noticed that this comment, which you moved from the .c to the .h, 
refers so_list_head.  so_list_head is a define present in the .c, so the 
comment makes less sense now.  What about bringing the define to the .h, 
and at the same time you could use it in the definition of ALL_SO_LIBS?

> +    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."

For consistency with all tests, I would suggest changing the test name 
to "get the list of shared libraries" (no period at the end, 
non-capitalized, neutral verb tense which I don't the name).

>  }
> 
> -mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
> +test_stop_on_solib_events
> +test_file_list_shared_libraries
> +mi_gdb_exit

I often see some tests ending with gdb_exit or mi_gdb_exit, but I don't 
think it's really required.  The code in lib/gdb.exp (e.g. gdb_exit) 
should take care of that, but I could be mistaken.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list
  2016-09-12 20:28 [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
                   ` (2 preceding siblings ...)
  2016-10-20  4:20 ` [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Simon Marchi
@ 2016-11-23 13:03 ` Pedro Alves
  2017-02-03 17:17 ` [PATCH v2 0/3] Shared libraries MI command Marc-Andre Laperle
  4 siblings, 0 replies; 26+ messages in thread
From: Pedro Alves @ 2016-11-23 13:03 UTC (permalink / raw)
  To: Marc-Andre Laperle, gdb-patches

Hi Marc-Andre,

On 09/12/2016 09:27 PM, Marc-Andre Laperle wrote:
> The target parameter in both solib_add and update_solib_list
> functions is not used anymore and as not been used for a while. This
> change removes the parameter to clean up the code a little bit.
> 
> gdb/ChangeLog:
> 
>         * infcmd.c (post_create_inferior): Remove unused argument in
>         call to solib_add.
>         * remote.c (remote_start_remote): Likewise.
>         * solib-frv.c (frv_fetch_objfile_link_map): Likewise.
>         * solib-svr4.c: (svr4_fetch_objfile_link_map): Likewise.
>         (enable_break): Likewise.
>         * solib.c (update_solib_list): Remove unused target argument
>         and its documentation.
>         (solib_add): Remove unused target argument.  Remove unused
>         argument in call to update_solib_list.
>         (info_sharedlibrary_command): Remove unused argument in call
>         to update_solib_list.
>         (sharedlibrary_command): Remove unused argument in call to
>         solib_add.
>         (handle_solib_event): Likewise.
>         (reload_shared_libraries): Likewise.
>         * solib.h (solib_add): Remove unused target argument.
> 
> Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>

OK.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 2/3] Add a better diagnostic message in mi_gdb_test
  2016-09-12 20:28 ` [PATCH 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle
  2016-10-20  4:24   ` Simon Marchi
@ 2016-11-23 13:03   ` Pedro Alves
  1 sibling, 0 replies; 26+ messages in thread
From: Pedro Alves @ 2016-11-23 13:03 UTC (permalink / raw)
  To: Marc-Andre Laperle, gdb-patches

On 09/12/2016 09:27 PM, Marc-Andre Laperle wrote:
> When using mi_gdb_test, if it fails because of the presence of
> unexpected output, the error message is only the message passed as
> the argument with no indication that there was an unexpected output.
> This change adds an additional text to the failure message to
> indicate that there was an unexpected output.
> 
> gdb/testsuite/ChangeLog:
> 
>         * lib/mi-support.exp (mi_gdb_test): Add additional message
>         for unexpected output.
> 
> Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>

OK.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] Add -file-list-shared-libraries MI command
  2016-09-12 20:28 ` [PATCH 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
  2016-10-14 21:20   ` Marc-André Laperle
  2016-10-20  5:05   ` Simon Marchi
@ 2016-11-23 13:06   ` Pedro Alves
  2017-01-04 17:19     ` Marc-André Laperle
  2 siblings, 1 reply; 26+ messages in thread
From: Pedro Alves @ 2016-11-23 13:06 UTC (permalink / raw)
  To: Marc-Andre Laperle, gdb-patches

Hi Marc-Andre,

Great that you're tackling this.  Thanks much for digging into GDB.  :-)
I like this.  As for following GDB's code standards, it's almost perfect.

But I have questions on the MI output, though.  See below.

On 09/12/2016 09:27 PM, Marc-Andre Laperle wrote:

> 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"@}]

I don't see where the documentation describes what the
attributes of each list element are.  Sorry if I missed it.

I find it surprising that the attributes output don't match 
attributes output by =library-loaded ?  I'd think they should
match.  That'd simplify the documentation too, as one place
would refer to the other for attributes list.

BTW, =library-loaded doesn't output from/to.  ISTR that that
was discussed and left out, because from/to assume there's
a contiguous range to report, while that's not true on all
targets (i.e., assumes a single segment).  So it seems to
me that that's a separate discussion/patch would better
be addressed in both places.

> +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;

error doesn't return.  No need for the 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);

So seems to me that the inner body of this loop would be better
calling a function that is shared with =library-loaded.

> +

> --- 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; \

Write explicit 'so != NULL'.

> +	 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 {} {

Looks like a good candidate for the the new proc_with_prefix.

> +    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."

Lowercase, no period at end, and use imperative:

	"get list of shared libraries"

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] Add -file-list-shared-libraries MI command
  2016-11-23 13:06   ` Pedro Alves
@ 2017-01-04 17:19     ` Marc-André Laperle
  2017-01-12 16:15       ` Pedro Alves
  0 siblings, 1 reply; 26+ messages in thread
From: Marc-André Laperle @ 2017-01-04 17:19 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

Thanks for the comments! A few questions/suggestions below.


On 2016-11-23 08:06 AM, Pedro Alves wrote:
> Hi Marc-Andre,
>
> Great that you're tackling this.  Thanks much for digging into GDB.  :-)
> I like this.  As for following GDB's code standards, it's almost perfect.
>
> But I have questions on the MI output, though.  See below.
>
> On 09/12/2016 09:27 PM, Marc-Andre Laperle wrote:
>
>> 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"@}]
> I don't see where the documentation describes what the
> attributes of each list element are.  Sorry if I missed it.
>
> I find it surprising that the attributes output don't match
> attributes output by =library-loaded ?  I'd think they should
> match.  That'd simplify the documentation too, as one place
> would refer to the other for attributes list.
>
> BTW, =library-loaded doesn't output from/to.  ISTR that that
> was discussed and left out, because from/to assume there's
> a contiguous range to report, while that's not true on all
> targets (i.e., assumes a single segment).  So it seems to
> me that that's a separate discussion/patch would better
> be addressed in both places.

Those attributes are from the "info shared" command which is what this 
new MI command is inspired from. The from/to are shown in Eclipse and I 
personally use it to know in which library a given stack frame is, in 
absence of debug symbols. I could change the attributes to be just like 
"=library-loaded" but it would be inconsistent with "info shared" and 
will remove information that was available before. Perhaps the best way 
forward would be to make all attributes the same as "=library-loaded" 
but also add the from/to.
To make the MI more future proof, it could be a list of from/to segments 
instead, but for now it will only one segment. What do you think?

>> +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;
> error doesn't return.  No need for the 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);
> So seems to me that the inner body of this loop would be better
> calling a function that is shared with =library-loaded.
>
>> +
>> --- 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; \
> Write explicit 'so != NULL'.
>
>> +	 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 {} {
> Looks like a good candidate for the the new proc_with_prefix.
>
>> +    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."
> Lowercase, no period at end, and use imperative:
>
> 	"get list of shared libraries"
>
> Thanks,
> Pedro Alves
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 3/3] Add -file-list-shared-libraries MI command
  2017-01-04 17:19     ` Marc-André Laperle
@ 2017-01-12 16:15       ` Pedro Alves
  0 siblings, 0 replies; 26+ messages in thread
From: Pedro Alves @ 2017-01-12 16:15 UTC (permalink / raw)
  To: Marc-André Laperle, gdb-patches

On 01/04/2017 05:18 PM, Marc-André Laperle wrote:

> Perhaps the best way
> forward would be to make all attributes the same as "=library-loaded"
> but also add the from/to.

I think so too.

> To make the MI more future proof, it could be a list of from/to segments
> instead, but for now it will only one segment. What do you think?

That's a good idea.  I like it.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 2/3] Add a better diagnostic message in mi_gdb_test
  2017-02-03 17:17 ` [PATCH v2 0/3] Shared libraries MI command Marc-Andre Laperle
  2017-02-03 17:16   ` [PATCH v2 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
  2017-02-03 17:16   ` [PATCH v2 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
@ 2017-02-03 17:16   ` Marc-Andre Laperle
  2 siblings, 0 replies; 26+ messages in thread
From: Marc-Andre Laperle @ 2017-02-03 17:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

When using mi_gdb_test, if it fails because of the presence of
unexpected output, the error message is only the message passed as
the argument with no indication that there was an unexpected output.
This change adds an additional text to the failure message to
indicate that there was an unexpected output.

gdb/testsuite/ChangeLog:

        * lib/mi-support.exp (mi_gdb_test): Add additional message
        for unexpected output.

Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
---
 gdb/testsuite/lib/mi-support.exp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 7c23922..5682b7e 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -824,7 +824,7 @@ proc mi_gdb_test { args } {
 	}
 	 -re ".*$mi_gdb_prompt\[ \]*$" {
 	    if ![string match "" $message] then {
-		fail "$message"
+		fail "$message (unexpected output)"
 	    }
 	    set result 1
 	}
-- 
2.9.3

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/3] Remove unused parameter in solib_add and update_solib_list
  2017-02-03 17:17 ` [PATCH v2 0/3] Shared libraries MI command Marc-Andre Laperle
@ 2017-02-03 17:16   ` Marc-Andre Laperle
  2017-02-03 17:16   ` [PATCH v2 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
  2017-02-03 17:16   ` [PATCH v2 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle
  2 siblings, 0 replies; 26+ messages in thread
From: Marc-Andre Laperle @ 2017-02-03 17:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

The target parameter in both solib_add and update_solib_list
functions is not used anymore and as not been used for a while. This
change removes the parameter to clean up the code a little bit.

gdb/ChangeLog:

        * infcmd.c (post_create_inferior): Remove unused argument in
        call to solib_add.
        * remote.c (remote_start_remote): Likewise.
        * solib-frv.c (frv_fetch_objfile_link_map): Likewise.
        * solib-svr4.c: (svr4_fetch_objfile_link_map): Likewise.
        (enable_break): Likewise.
        * solib.c (update_solib_list): Remove unused target argument
        and its documentation.
        (solib_add): Remove unused target argument.  Remove unused
        argument in call to update_solib_list.
        (info_sharedlibrary_command): Remove unused argument in call
        to update_solib_list.
        (sharedlibrary_command): Remove unused argument in call to
        solib_add.
        (handle_solib_event): Likewise.
        (reload_shared_libraries): Likewise.
        * solib.h (solib_add): Remove unused target argument.

Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
---
 gdb/infcmd.c     |  2 +-
 gdb/remote.c     |  2 +-
 gdb/solib-frv.c  |  2 +-
 gdb/solib-svr4.c |  6 +++---
 gdb/solib.c      | 28 ++++++++++------------------
 gdb/solib.h      |  2 +-
 6 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index d836162..d41e609 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -458,7 +458,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
 	  /* If the solist is global across processes, there's no need to
 	     refetch it here.  */
 	  if (!gdbarch_has_global_solist (target_gdbarch ()))
-	    solib_add (NULL, 0, target, auto_solib_add);
+	    solib_add (NULL, 0, auto_solib_add);
 	}
     }
 
diff --git a/gdb/remote.c b/gdb/remote.c
index 3befbd3..ebe7ee2 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -4142,7 +4142,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
   /* On OSs where the list of libraries is global to all
      processes, we fetch them early.  */
   if (gdbarch_has_global_solist (target_gdbarch ()))
-    solib_add (NULL, from_tty, target, auto_solib_add);
+    solib_add (NULL, from_tty, auto_solib_add);
 
   if (target_is_non_stop_p ())
     {
diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
index 261b568..e8d5f20 100644
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -1131,7 +1131,7 @@ frv_fetch_objfile_link_map (struct objfile *objfile)
 
   /* Cause frv_current_sos() to be run if it hasn't been already.  */
   if (main_lm_addr == 0)
-    solib_add (0, 0, 0, 1);
+    solib_add (0, 0, 1);
 
   /* frv_current_sos() will set main_lm_addr for the main executable.  */
   if (objfile == symfile_objfile)
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 4f52251..4cb6127 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1618,7 +1618,7 @@ svr4_fetch_objfile_link_map (struct objfile *objfile)
 
   /* Cause svr4_current_sos() to be run if it hasn't been already.  */
   if (info->main_lm_addr == 0)
-    solib_add (NULL, 0, &current_target, auto_solib_add);
+    solib_add (NULL, 0, auto_solib_add);
 
   /* svr4_current_sos() will set main_lm_addr for the main executable.  */
   if (objfile == symfile_objfile)
@@ -2277,7 +2277,7 @@ enable_break (struct svr4_info *info, int from_tty)
      mean r_brk has already been relocated.  Assume the dynamic linker
      is the object containing r_brk.  */
 
-  solib_add (NULL, from_tty, &current_target, auto_solib_add);
+  solib_add (NULL, from_tty, auto_solib_add);
   sym_addr = 0;
   if (info->debug_base && solib_svr4_r_map (info) != 0)
     sym_addr = solib_svr4_r_brk (info);
@@ -2453,7 +2453,7 @@ enable_break (struct svr4_info *info, int from_tty)
 	  info->debug_loader_name = xstrdup (interp_name);
 	  info->debug_loader_offset_p = 1;
 	  info->debug_loader_offset = load_addr;
-	  solib_add (NULL, from_tty, &current_target, auto_solib_add);
+	  solib_add (NULL, from_tty, auto_solib_add);
 	}
 
       /* Record the relocated start and end address of the dynamic linker
diff --git a/gdb/solib.c b/gdb/solib.c
index fc45133..38737b6 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -763,17 +763,10 @@ solib_used (const struct so_list *const known)
    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.
+   we're doing.  */
 
-   If TARGET is non-null, add the sections of all new shared objects
-   to TARGET's section table.  Note that this doesn't remove any
-   sections for shared objects that have been unloaded, and it
-   doesn't check to see if the new shared objects are already present in
-   the section table.  But we only use this for core files and
-   processes we've just attached to, so that's okay.  */
-
-static void
-update_solib_list (int from_tty, struct target_ops *target)
+void
+update_solib_list (int from_tty)
 {
   const struct target_so_ops *ops = solib_ops (target_gdbarch ());
   struct so_list *inferior = ops->current_sos();
@@ -974,11 +967,10 @@ libpthread_solib_p (struct so_list *so)
    If READSYMS is 0, defer reading symbolic information until later
    but still do any needed low level processing.
 
-   FROM_TTY and TARGET are as described for update_solib_list, above.  */
+   FROM_TTY is described for update_solib_list, above.  */
 
 void
-solib_add (const char *pattern, int from_tty,
-	   struct target_ops *target, int readsyms)
+solib_add (const char *pattern, int from_tty, int readsyms)
 {
   struct so_list *gdb;
 
@@ -1003,7 +995,7 @@ solib_add (const char *pattern, int from_tty,
 	error (_("Invalid regexp: %s"), re_err);
     }
 
-  update_solib_list (from_tty, target);
+  update_solib_list (from_tty);
 
   /* Walk the list of currently loaded shared libraries, and read
      symbols for any that match the pattern --- or any whose symbols
@@ -1086,7 +1078,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
   /* "0x", a little whitespace, and two hex digits per byte of pointers.  */
   addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
 
-  update_solib_list (from_tty, 0);
+  update_solib_list (from_tty);
 
   /* make_cleanup_ui_out_table_begin_end needs to know the number of
      rows, so we need to make two passes over the libs.  */
@@ -1276,7 +1268,7 @@ static void
 sharedlibrary_command (char *args, int from_tty)
 {
   dont_repeat ();
-  solib_add (args, from_tty, (struct target_ops *) 0, 1);
+  solib_add (args, from_tty, 1);
 }
 
 /* Implements the command "nosharedlibrary", which discards symbols
@@ -1323,7 +1315,7 @@ handle_solib_event (void)
      be adding them automatically.  Switch terminal for any messages
      produced by breakpoint_re_set.  */
   target_terminal_ours_for_output ();
-  solib_add (NULL, 0, &current_target, auto_solib_add);
+  solib_add (NULL, 0, auto_solib_add);
   target_terminal_inferior ();
 }
 
@@ -1441,7 +1433,7 @@ reload_shared_libraries (char *ignored, int from_tty,
      removed.  Call it only after the solib target has been initialized by
      solib_create_inferior_hook.  */
 
-  solib_add (NULL, 0, NULL, auto_solib_add);
+  solib_add (NULL, 0, auto_solib_add);
 
   breakpoint_re_set ();
 
diff --git a/gdb/solib.h b/gdb/solib.h
index dd07636..1b46849 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -35,7 +35,7 @@ extern void clear_solib (void);
 
 /* Called to add symbols from a shared library to gdb's symbol table.  */
 
-extern void solib_add (const char *, int, struct target_ops *, int);
+extern void solib_add (const char *, int, int);
 extern int solib_read_symbols (struct so_list *, symfile_add_flags);
 
 /* Function to be called when the inferior starts up, to discover the
-- 
2.9.3

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 3/3] Add -file-list-shared-libraries MI command
  2017-02-03 17:17 ` [PATCH v2 0/3] Shared libraries MI command Marc-Andre Laperle
  2017-02-03 17:16   ` [PATCH v2 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
@ 2017-02-03 17:16   ` Marc-Andre Laperle
  2017-02-06 12:40     ` Pedro Alves
  2017-02-03 17:16   ` [PATCH v2 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle
  2 siblings, 1 reply; 26+ messages in thread
From: Marc-Andre Laperle @ 2017-02-03 17:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

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/MI Async Records): Update documentation of library-loaded with new
        field.

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.
        * mi/mi-interp.c (mi_output_solib_attribs): New Function.
        * mi/mi-interp.h: New file.
        * solib.c (info_sharedlibrary_command): Replace for loop with
        ALL_SO_LIBS macro
        * solib.h (update_solib_list): New function declaration.
        (so_list_head): Move macro.
        * 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               | 25 +++++++++++++-----
 gdb/mi/mi-cmd-file.c              | 54 +++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-cmds.c                  |  2 ++
 gdb/mi/mi-cmds.h                  |  1 +
 gdb/mi/mi-interp.c                | 35 +++++++++++++++++++------
 gdb/mi/mi-interp.h                | 27 ++++++++++++++++++++
 gdb/solib.c                       | 21 ++-------------
 gdb/solib.h                       | 21 +++++++++++++++
 gdb/solist.h                      |  5 ++++
 gdb/testsuite/gdb.mi/mi-solib.exp | 49 ++++++++++++++++++++++++-----------
 10 files changed, 191 insertions(+), 49 deletions(-)
 create mode 100644 gdb/mi/mi-interp.h

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index b9b4c82..b6fc0aa 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -26545,8 +26545,8 @@ 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
+notification has 5 fields---@var{id}, @var{target-name},
+@var{host-name}, @var{symbols-loaded} and @var{ranges}.  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
@@ -26556,7 +26556,8 @@ and should not be relied on to convey any useful information.  The
 @var{thread-group} field, if present, specifies the id of the thread
 group in whose context the library was loaded.  If the field is
 absent, it means the library was loaded in the context of all present
-thread groups.
+thread groups. The @var{ranges} field specifies the ranges of addresses belonging
+to this library.
 
 @item =library-unloaded,...
 Reports that a library was unloaded by the program.  This notification
@@ -31477,26 +31478,36 @@ 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}.
+The corresponding @value{GDBN} command is @samp{info shared}. The fields
+have a similar meaning than the @code{=library-loaded} notification.
 
 @subsubheading Example
-N.A.
+@smallexample
+(gdb)
+-file-list-exec-source-files
+^done,shared-libraries=[
+@{id="/lib/libfoo.so",target-name="/lib/libfoo.so",host-name="/lib/libfoo.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x72815989",to="0x728162c0"@}]@},
+@{id="/lib/libbar.so",target-name="/lib/libbar.so",host-name="/lib/libbar.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x76ee48c0",to="0x76ee9160"@}]@}]
+(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 71e2845..f38cb71 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -20,11 +20,15 @@
 #include "defs.h"
 #include "mi-cmds.h"
 #include "mi-getopt.h"
+#include "mi-interp.h"
 #include "ui-out.h"
 #include "symtab.h"
 #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.  */
@@ -106,3 +110,53 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
 
   uiout->end (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]"));
+    }
+
+  if (pattern != NULL)
+    {
+      const char *re_err = re_comp (pattern);
+
+      if (re_err != NULL)
+	error (_("Invalid regexp: %s"), re_err);
+    }
+
+  update_solib_list (1);
+
+  /* Print the table header.  */
+  struct cleanup* cleanup = make_cleanup_ui_out_list_begin_end (uiout, "shared-libraries");
+
+  ALL_SO_LIBS (so)
+    {
+      if (so->so_name[0] == '\0')
+	continue;
+      if (pattern != NULL && !re_exec (so->so_name))
+	continue;
+
+      struct cleanup * tuple_clean_up
+        = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+      mi_output_solib_attribs (uiout, so);
+
+      do_cleanups (tuple_clean_up);
+    }
+
+  do_cleanups (cleanup);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index abb70bd..b7494ce 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 d0906e6..fcadfff 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/mi/mi-interp.c b/gdb/mi/mi-interp.c
index aa76989..a5308e3 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1119,6 +1119,32 @@ mi_on_resume (ptid_t ptid)
     }
 }
 
+void
+mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
+{
+  struct gdbarch *gdbarch = target_gdbarch ();
+
+  uiout->field_string ("id", solib->so_original_name);
+  uiout->field_string ("target-name", solib->so_original_name);
+  uiout->field_string ("host-name", solib->so_name);
+  uiout->field_int ("symbols-loaded", solib->symbols_loaded);
+  if (!gdbarch_has_global_solist (target_gdbarch ()))
+    {
+      uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
+    }
+  struct cleanup *cleanup
+    = make_cleanup_ui_out_list_begin_end (uiout, "ranges");
+  struct cleanup *tuple_clean_up
+    = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+  if (solib->addr_high != 0)
+    {
+      uiout->field_core_addr ("from", gdbarch, solib->addr_low);
+      uiout->field_core_addr ("to", gdbarch, solib->addr_high);
+    }
+  do_cleanups (tuple_clean_up);
+  do_cleanups (cleanup);
+}
+
 static void
 mi_solib_loaded (struct so_list *solib)
 {
@@ -1140,14 +1166,7 @@ mi_solib_loaded (struct so_list *solib)
 
       uiout->redirect (mi->event_channel);
 
-      uiout->field_string ("id", solib->so_original_name);
-      uiout->field_string ("target-name", solib->so_original_name);
-      uiout->field_string ("host-name", solib->so_name);
-      uiout->field_int ("symbols-loaded", solib->symbols_loaded);
-      if (!gdbarch_has_global_solist (target_gdbarch ()))
-	{
-	  uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
-	}
+      mi_output_solib_attribs (uiout, solib);
 
       uiout->redirect (NULL);
 
diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
new file mode 100644
index 0000000..5b7b9f2
--- /dev/null
+++ b/gdb/mi/mi-interp.h
@@ -0,0 +1,27 @@
+/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef MI_INTERP_H
+#define MI_INTERP_H
+
+/* Output the shared object attributes to UIOUT.  */
+
+void mi_output_solib_attribs (ui_out *uiout, struct so_list *solib);
+
+#endif
diff --git a/gdb/solib.c b/gdb/solib.c
index 38737b6..af94383 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -89,9 +89,6 @@ set_solib_ops (struct gdbarch *gdbarch, const struct target_so_ops *new_ops)
    configuration needs to call set_solib_ops.  */
 struct target_so_ops *current_target_so_ops;
 
-/* List of known shared objects */
-#define so_list_head current_program_space->so_list
-
 /* Local function prototypes */
 
 /* If non-empty, this is a search path for loading non-absolute shared library
@@ -749,21 +746,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)
@@ -1105,7 +1088,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
 
   uiout->table_body ();
 
-  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 1b46849..e91fb75 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -28,6 +28,9 @@ struct program_space;
 
 #include "symfile-add-flags.h"
 
+/* List of known shared objects */
+#define so_list_head current_program_space->so_list
+
 /* Called when we free all symtabs, to free the shared library information
    as well.  */
 
@@ -75,6 +78,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 9c7e965..f2f093d 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -24,6 +24,11 @@
 #include "symtab.h"
 #include "gdb_bfd.h"
 
+#define ALL_SO_LIBS(so) \
+    for (so = so_list_head; \
+	 so != NULL; \
+	 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 575cb97..ff933e7 100644
--- a/gdb/testsuite/gdb.mi/mi-solib.exp
+++ b/gdb/testsuite/gdb.mi/mi-solib.exp
@@ -48,27 +48,46 @@ 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_with_prefix 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_with_prefix 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=\\\[\{id=\".*${libname}.so\",target-name=\".*${libname}.so\",host-name=\".*${libname}.so\",symbols-loaded=\"1\",thread-group=\".*\",ranges=\\\[\{from=\".*\",to=\".*\"\}]\}]" \
+	"get the list of shared libraries"
 }
 
-mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
+test_stop_on_solib_events
+test_file_list_shared_libraries
-- 
2.9.3

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 0/3] Shared libraries MI command
  2016-09-12 20:28 [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
                   ` (3 preceding siblings ...)
  2016-11-23 13:03 ` Pedro Alves
@ 2017-02-03 17:17 ` Marc-Andre Laperle
  2017-02-03 17:16   ` [PATCH v2 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
                     ` (2 more replies)
  4 siblings, 3 replies; 26+ messages in thread
From: Marc-Andre Laperle @ 2017-02-03 17:17 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

This is the version 2 of this patchset
https://sourceware.org/ml/gdb-patches/2016-09/msg00091.html

Patches 1 and 2 were already OK'd but are rebased. Patch 3 was modified
following Pedro's and Simon's comments.

Marc-Andre Laperle (3):
  Remove unused parameter in solib_add and update_solib_list
  Add a better diagnostic message in mi_gdb_test
  Add -file-list-shared-libraries MI command

 gdb/doc/gdb.texinfo               | 25 +++++++++++++-----
 gdb/infcmd.c                      |  2 +-
 gdb/mi/mi-cmd-file.c              | 54 +++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-cmds.c                  |  2 ++
 gdb/mi/mi-cmds.h                  |  1 +
 gdb/mi/mi-interp.c                | 35 +++++++++++++++++++------
 gdb/mi/mi-interp.h                | 27 ++++++++++++++++++++
 gdb/remote.c                      |  2 +-
 gdb/solib-frv.c                   |  2 +-
 gdb/solib-svr4.c                  |  6 ++---
 gdb/solib.c                       | 47 ++++++++--------------------------
 gdb/solib.h                       | 23 ++++++++++++++++-
 gdb/solist.h                      |  5 ++++
 gdb/testsuite/gdb.mi/mi-solib.exp | 49 ++++++++++++++++++++++++-----------
 gdb/testsuite/lib/mi-support.exp  |  2 +-
 15 files changed, 208 insertions(+), 74 deletions(-)
 create mode 100644 gdb/mi/mi-interp.h

-- 
2.9.3

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/3] Add -file-list-shared-libraries MI command
  2017-02-03 17:16   ` [PATCH v2 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
@ 2017-02-06 12:40     ` Pedro Alves
  2017-02-28 22:08       ` [Patch v3] " Marc-Andre Laperle
  0 siblings, 1 reply; 26+ messages in thread
From: Pedro Alves @ 2017-02-06 12:40 UTC (permalink / raw)
  To: Marc-Andre Laperle, gdb-patches

Hi Marc-Andre,

Could you include a gdb/NEWS change as well, please?

On 02/03/2017 05:15 PM, Marc-Andre Laperle wrote:

>  @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
> +notification has 5 fields---@var{id}, @var{target-name},
> +@var{host-name}, @var{symbols-loaded} and @var{ranges}.  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
> @@ -26556,7 +26556,8 @@ and should not be relied on to convey any useful information.  The
>  @var{thread-group} field, if present, specifies the id of the thread
>  group in whose context the library was loaded.  If the field is
>  absent, it means the library was loaded in the context of all present
> -thread groups.
> +thread groups. The @var{ranges} field specifies the ranges of addresses belonging
> +to this library.

Could you add some description of the subfields of the ranges
field?  Something like "each range has the following fields", or some
such.  Particularly important to mention I think is
whether "to" is inclusive or exclusive. 

E.g., from the "Memory Region Attributes" section of the manual:

 @item Lo Address
 The address defining the inclusive lower bound of the memory region.

 @item Hi Address
 The address defining the exclusive upper bound of the memory region.

Another from range stepping vCont action description:

 @item r @var{start},@var{end}
 Step once, and then keep stepping as long as the thread stops at
 addresses between @var{start} (inclusive) and @var{end} (exclusive).

It should be inclusive, in order to handle a range that covers all
the way to the end of the address space correctly (otherwise
one-past-the-end wraps around).   However, seems like the current
code puts an exclusive end range in high_addr, since
"target_section::endaddr" is one-past-the-end.  :-(

This comment in struct so_list would be nice to update somehow too:

    /* Record the range of addresses belonging to this shared library.
       There may not be just one (e.g. if two segments are relocated
       differently); but this is only used for "info sharedlibrary".  */
    CORE_ADDR addr_low, addr_high;

The "only used for" part is now inaccurate.

I'd suggest adding some small comment about the multiple-segments
case to the MI code that prints the ranges, so other folks running
into that code understand that there's something to be improved there.

> --- a/gdb/mi/mi-cmd-file.c
> +++ b/gdb/mi/mi-cmd-file.c
> @@ -20,11 +20,15 @@
>  #include "defs.h"
>  #include "mi-cmds.h"
>  #include "mi-getopt.h"
> +#include "mi-interp.h"
>  #include "ui-out.h"
>  #include "symtab.h"
>  #include "source.h"
>  #include "objfiles.h"
>  #include "psymtab.h"
> +#include "solib.h"
> +#include "solist.h"
> +#include "xregex.h"

Don't include "xregex.h", include gdb_regex.h:

 gdb/contrib/ari/gdb_ari.sh:318:BEGIN { doc["xregex.h"] = "\
 gdb/contrib/ari/gdb_ari.sh:319:Do not include xregex.h, instead include gdb_regex.h"
 gdb/contrib/ari/gdb_ari.sh:320:    category["xregex.h"] = ari_regression


> +
> +void
> +mi_cmd_file_list_shared_libraries (char *command, char **argv, int argc)

Add a

/* See foo.h.  */

comment.

> +{
> +  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]"));
> +    }
> +
> +  if (pattern != NULL)
> +    {
> +      const char *re_err = re_comp (pattern);
> +
> +      if (re_err != NULL)
> +	error (_("Invalid regexp: %s"), re_err);
> +    }
> +
> +  update_solib_list (1);
> +
> +  /* Print the table header.  */
> +  struct cleanup* cleanup = make_cleanup_ui_out_list_begin_end (uiout, "shared-libraries");

Formatting:

 - Space before '*', not after.
 - Too long line.

Write:

  struct cleanup *cleanup
    = make_cleanup_ui_out_list_begin_end (uiout, "shared-libraries");

> +
> +  ALL_SO_LIBS (so)
> +    {
> +      if (so->so_name[0] == '\0')
> +	continue;
> +      if (pattern != NULL && !re_exec (so->so_name))
> +	continue;
> +
> +      struct cleanup * tuple_clean_up

No space after *.

> +        = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
> +      mi_output_solib_attribs (uiout, so);
> +
> +      do_cleanups (tuple_clean_up);
> +    }
> +
> +  do_cleanups (cleanup);
> +}
+

> +void
> +mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)

/* See bar.h.  */

> +{
> +  struct gdbarch *gdbarch = target_gdbarch ();
> +
> +  uiout->field_string ("id", solib->so_original_name);
> +  uiout->field_string ("target-name", solib->so_original_name);
> +  uiout->field_string ("host-name", solib->so_name);
> +  uiout->field_int ("symbols-loaded", solib->symbols_loaded);
> +  if (!gdbarch_has_global_solist (target_gdbarch ()))
> +    {
> +      uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
> +    }

While at it, please remove the unnecessary {}.  (I know you're just
moving that code.)

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [Patch v3] Add -file-list-shared-libraries MI command
  2017-02-06 12:40     ` Pedro Alves
@ 2017-02-28 22:08       ` Marc-Andre Laperle
  2017-03-01 15:50         ` Marc-André Laperle
  2017-03-01 16:12         ` Eli Zaretskii
  0 siblings, 2 replies; 26+ messages in thread
From: Marc-Andre Laperle @ 2017-02-28 22:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

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/MI Async Records): Update documentation of library-loaded with new
        field.

gdb/ChangeLog:

        * NEWS: Add an entry about new '-file-list-shared-libraries' command.
        * 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.
        * mi/mi-interp.c (mi_output_solib_attribs): New Function.
        * mi/mi-interp.h: New file.
        * solib.c (info_sharedlibrary_command): Replace for loop with
        ALL_SO_LIBS macro
        * solib.h (update_solib_list): New function declaration.
        (so_list_head): Move macro.
        * 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/NEWS                          |  4 +++
 gdb/doc/gdb.texinfo               | 34 ++++++++++++++++++-----
 gdb/mi/mi-cmd-file.c              | 57 +++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-cmds.c                  |  2 ++
 gdb/mi/mi-cmds.h                  |  1 +
 gdb/mi/mi-interp.c                | 36 +++++++++++++++++++------
 gdb/mi/mi-interp.h                | 27 +++++++++++++++++++
 gdb/solib.c                       | 21 ++-------------
 gdb/solib.h                       | 21 +++++++++++++++
 gdb/solist.h                      | 10 ++++++-
 gdb/testsuite/gdb.mi/mi-solib.exp | 49 ++++++++++++++++++++++-----------
 11 files changed, 212 insertions(+), 50 deletions(-)
 create mode 100644 gdb/mi/mi-interp.h

diff --git a/gdb/NEWS b/gdb/NEWS
index 21e8cd3..a5c5e0d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -68,6 +68,10 @@ flash-erase
   Erases all the flash memory regions reported by the target.  This is
   equivalent to the CLI command flash-erase.
 
+-file-list-shared-libraries
+  List the shared libraries in the program.  This is
+  equivalent to the CLI command "info shared".
+
 *** Changes in GDB 7.12
 
 * GDB and GDBserver now build with a C++ compiler by default.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index b9b4c82..097a608 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -26545,8 +26545,8 @@ 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
+notification has 5 fields---@var{id}, @var{target-name},
+@var{host-name}, @var{symbols-loaded} and @var{ranges}.  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
@@ -26556,7 +26556,8 @@ and should not be relied on to convey any useful information.  The
 @var{thread-group} field, if present, specifies the id of the thread
 group in whose context the library was loaded.  If the field is
 absent, it means the library was loaded in the context of all present
-thread groups.
+thread groups. The @var{ranges} field specifies the ranges of addresses belonging
+to this library.
 
 @item =library-unloaded,...
 Reports that a library was unloaded by the program.  This notification
@@ -31477,26 +31478,45 @@ 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}.
+The corresponding @value{GDBN} command is @samp{info shared}. The fields
+have a similar meaning than the @code{=library-loaded} notification.
+The @code{ranges} field specifies the muliple segments belonging to this
+library.  Each range has the following fields:
+
+@table @samp
+@item from
+The address defining the inclusive lower bound of the segment.
+@item to
+The address defining the exclusive upper bound of the segment.
+@end table
 
 @subsubheading Example
-N.A.
+@smallexample
+(gdb)
+-file-list-exec-source-files
+^done,shared-libraries=[
+@{id="/lib/libfoo.so",target-name="/lib/libfoo.so",host-name="/lib/libfoo.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x72815989",to="0x728162c0"@}]@},
+@{id="/lib/libbar.so",target-name="/lib/libbar.so",host-name="/lib/libbar.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x76ee48c0",to="0x76ee9160"@}]@}]
+(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 71e2845..a2ad392 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -20,11 +20,15 @@
 #include "defs.h"
 #include "mi-cmds.h"
 #include "mi-getopt.h"
+#include "mi-interp.h"
 #include "ui-out.h"
 #include "symtab.h"
 #include "source.h"
 #include "objfiles.h"
 #include "psymtab.h"
+#include "solib.h"
+#include "solist.h"
+#include "gdb_regex.h"
 
 /* Return to the client the absolute path and line number of the 
    current file being executed.  */
@@ -106,3 +110,56 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
 
   uiout->end (ui_out_type_list);
 }
+
+/* See mi-cmds.h.  */
+
+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]"));
+    }
+
+  if (pattern != NULL)
+    {
+      const char *re_err = re_comp (pattern);
+
+      if (re_err != NULL)
+	error (_("Invalid regexp: %s"), re_err);
+    }
+
+  update_solib_list (1);
+
+  /* Print the table header.  */
+  struct cleanup *cleanup
+    = make_cleanup_ui_out_list_begin_end (uiout, "shared-libraries");
+
+  ALL_SO_LIBS (so)
+    {
+      if (so->so_name[0] == '\0')
+	continue;
+      if (pattern != NULL && !re_exec (so->so_name))
+	continue;
+
+      struct cleanup *tuple_clean_up
+        = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+      mi_output_solib_attribs (uiout, so);
+
+      do_cleanups (tuple_clean_up);
+    }
+
+  do_cleanups (cleanup);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index abb70bd..b7494ce 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 d0906e6..fcadfff 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/mi/mi-interp.c b/gdb/mi/mi-interp.c
index aa76989..1a26818 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1119,6 +1119,33 @@ mi_on_resume (ptid_t ptid)
     }
 }
 
+/* See mi-interp.h.  */
+
+void
+mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
+{
+  struct gdbarch *gdbarch = target_gdbarch ();
+
+  uiout->field_string ("id", solib->so_original_name);
+  uiout->field_string ("target-name", solib->so_original_name);
+  uiout->field_string ("host-name", solib->so_name);
+  uiout->field_int ("symbols-loaded", solib->symbols_loaded);
+  if (!gdbarch_has_global_solist (target_gdbarch ()))
+      uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
+
+  struct cleanup *cleanup
+    = make_cleanup_ui_out_list_begin_end (uiout, "ranges");
+  struct cleanup *tuple_clean_up
+    = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+  if (solib->addr_high != 0)
+    {
+      uiout->field_core_addr ("from", gdbarch, solib->addr_low);
+      uiout->field_core_addr ("to", gdbarch, solib->addr_high);
+    }
+  do_cleanups (tuple_clean_up);
+  do_cleanups (cleanup);
+}
+
 static void
 mi_solib_loaded (struct so_list *solib)
 {
@@ -1140,14 +1167,7 @@ mi_solib_loaded (struct so_list *solib)
 
       uiout->redirect (mi->event_channel);
 
-      uiout->field_string ("id", solib->so_original_name);
-      uiout->field_string ("target-name", solib->so_original_name);
-      uiout->field_string ("host-name", solib->so_name);
-      uiout->field_int ("symbols-loaded", solib->symbols_loaded);
-      if (!gdbarch_has_global_solist (target_gdbarch ()))
-	{
-	  uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
-	}
+      mi_output_solib_attribs (uiout, solib);
 
       uiout->redirect (NULL);
 
diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
new file mode 100644
index 0000000..5b7b9f2
--- /dev/null
+++ b/gdb/mi/mi-interp.h
@@ -0,0 +1,27 @@
+/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef MI_INTERP_H
+#define MI_INTERP_H
+
+/* Output the shared object attributes to UIOUT.  */
+
+void mi_output_solib_attribs (ui_out *uiout, struct so_list *solib);
+
+#endif
diff --git a/gdb/solib.c b/gdb/solib.c
index 38737b6..af94383 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -89,9 +89,6 @@ set_solib_ops (struct gdbarch *gdbarch, const struct target_so_ops *new_ops)
    configuration needs to call set_solib_ops.  */
 struct target_so_ops *current_target_so_ops;
 
-/* List of known shared objects */
-#define so_list_head current_program_space->so_list
-
 /* Local function prototypes */
 
 /* If non-empty, this is a search path for loading non-absolute shared library
@@ -749,21 +746,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)
@@ -1105,7 +1088,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
 
   uiout->table_body ();
 
-  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 1b46849..e91fb75 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -28,6 +28,9 @@ struct program_space;
 
 #include "symfile-add-flags.h"
 
+/* List of known shared objects */
+#define so_list_head current_program_space->so_list
+
 /* Called when we free all symtabs, to free the shared library information
    as well.  */
 
@@ -75,6 +78,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 9c7e965..6e2ab66 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -24,6 +24,11 @@
 #include "symtab.h"
 #include "gdb_bfd.h"
 
+#define ALL_SO_LIBS(so) \
+    for (so = so_list_head; \
+	 so != NULL; \
+	 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;
@@ -74,7 +79,10 @@ struct so_list
 
     /* Record the range of addresses belonging to this shared library.
        There may not be just one (e.g. if two segments are relocated
-       differently); but this is only used for "info sharedlibrary".  */
+       differently).  This is used for "info sharedlibrary" and
+       the MI command "-file-list-shared-libraries".  The later has a format
+       that supports outputting multiple segments once the related code
+       supports them.  */
     CORE_ADDR addr_low, addr_high;
   };
 
diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp
index 575cb97..ff933e7 100644
--- a/gdb/testsuite/gdb.mi/mi-solib.exp
+++ b/gdb/testsuite/gdb.mi/mi-solib.exp
@@ -48,27 +48,46 @@ 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_with_prefix 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_with_prefix 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=\\\[\{id=\".*${libname}.so\",target-name=\".*${libname}.so\",host-name=\".*${libname}.so\",symbols-loaded=\"1\",thread-group=\".*\",ranges=\\\[\{from=\".*\",to=\".*\"\}]\}]" \
+	"get the list of shared libraries"
 }
 
-mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
+test_stop_on_solib_events
+test_file_list_shared_libraries
-- 
2.9.3

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Patch v3] Add -file-list-shared-libraries MI command
  2017-02-28 22:08       ` [Patch v3] " Marc-Andre Laperle
@ 2017-03-01 15:50         ` Marc-André Laperle
  2017-03-01 16:12         ` Eli Zaretskii
  1 sibling, 0 replies; 26+ messages in thread
From: Marc-André Laperle @ 2017-03-01 15:50 UTC (permalink / raw)
  To: gdb-patches

This patch should address all previous comments.

Regards,
Marc-André

On 2017-02-28 05:07 PM, Marc-Andre Laperle wrote:
> 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/MI Async Records): Update documentation of library-loaded with new
>          field.
>
> gdb/ChangeLog:
>
>          * NEWS: Add an entry about new '-file-list-shared-libraries' command.
>          * 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.
>          * mi/mi-interp.c (mi_output_solib_attribs): New Function.
>          * mi/mi-interp.h: New file.
>          * solib.c (info_sharedlibrary_command): Replace for loop with
>          ALL_SO_LIBS macro
>          * solib.h (update_solib_list): New function declaration.
>          (so_list_head): Move macro.
>          * 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/NEWS                          |  4 +++
>   gdb/doc/gdb.texinfo               | 34 ++++++++++++++++++-----
>   gdb/mi/mi-cmd-file.c              | 57 +++++++++++++++++++++++++++++++++++++++
>   gdb/mi/mi-cmds.c                  |  2 ++
>   gdb/mi/mi-cmds.h                  |  1 +
>   gdb/mi/mi-interp.c                | 36 +++++++++++++++++++------
>   gdb/mi/mi-interp.h                | 27 +++++++++++++++++++
>   gdb/solib.c                       | 21 ++-------------
>   gdb/solib.h                       | 21 +++++++++++++++
>   gdb/solist.h                      | 10 ++++++-
>   gdb/testsuite/gdb.mi/mi-solib.exp | 49 ++++++++++++++++++++++-----------
>   11 files changed, 212 insertions(+), 50 deletions(-)
>   create mode 100644 gdb/mi/mi-interp.h
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 21e8cd3..a5c5e0d 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -68,6 +68,10 @@ flash-erase
>     Erases all the flash memory regions reported by the target.  This is
>     equivalent to the CLI command flash-erase.
>   
> +-file-list-shared-libraries
> +  List the shared libraries in the program.  This is
> +  equivalent to the CLI command "info shared".
> +
>   *** Changes in GDB 7.12
>   
>   * GDB and GDBserver now build with a C++ compiler by default.
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index b9b4c82..097a608 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -26545,8 +26545,8 @@ 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
> +notification has 5 fields---@var{id}, @var{target-name},
> +@var{host-name}, @var{symbols-loaded} and @var{ranges}.  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
> @@ -26556,7 +26556,8 @@ and should not be relied on to convey any useful information.  The
>   @var{thread-group} field, if present, specifies the id of the thread
>   group in whose context the library was loaded.  If the field is
>   absent, it means the library was loaded in the context of all present
> -thread groups.
> +thread groups. The @var{ranges} field specifies the ranges of addresses belonging
> +to this library.
>   
>   @item =library-unloaded,...
>   Reports that a library was unloaded by the program.  This notification
> @@ -31477,26 +31478,45 @@ 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}.
> +The corresponding @value{GDBN} command is @samp{info shared}. The fields
> +have a similar meaning than the @code{=library-loaded} notification.
> +The @code{ranges} field specifies the muliple segments belonging to this
> +library.  Each range has the following fields:
> +
> +@table @samp
> +@item from
> +The address defining the inclusive lower bound of the segment.
> +@item to
> +The address defining the exclusive upper bound of the segment.
> +@end table
>   
>   @subsubheading Example
> -N.A.
> +@smallexample
> +(gdb)
> +-file-list-exec-source-files
> +^done,shared-libraries=[
> +@{id="/lib/libfoo.so",target-name="/lib/libfoo.so",host-name="/lib/libfoo.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x72815989",to="0x728162c0"@}]@},
> +@{id="/lib/libbar.so",target-name="/lib/libbar.so",host-name="/lib/libbar.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x76ee48c0",to="0x76ee9160"@}]@}]
> +(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 71e2845..a2ad392 100644
> --- a/gdb/mi/mi-cmd-file.c
> +++ b/gdb/mi/mi-cmd-file.c
> @@ -20,11 +20,15 @@
>   #include "defs.h"
>   #include "mi-cmds.h"
>   #include "mi-getopt.h"
> +#include "mi-interp.h"
>   #include "ui-out.h"
>   #include "symtab.h"
>   #include "source.h"
>   #include "objfiles.h"
>   #include "psymtab.h"
> +#include "solib.h"
> +#include "solist.h"
> +#include "gdb_regex.h"
>   
>   /* Return to the client the absolute path and line number of the
>      current file being executed.  */
> @@ -106,3 +110,56 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
>   
>     uiout->end (ui_out_type_list);
>   }
> +
> +/* See mi-cmds.h.  */
> +
> +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]"));
> +    }
> +
> +  if (pattern != NULL)
> +    {
> +      const char *re_err = re_comp (pattern);
> +
> +      if (re_err != NULL)
> +	error (_("Invalid regexp: %s"), re_err);
> +    }
> +
> +  update_solib_list (1);
> +
> +  /* Print the table header.  */
> +  struct cleanup *cleanup
> +    = make_cleanup_ui_out_list_begin_end (uiout, "shared-libraries");
> +
> +  ALL_SO_LIBS (so)
> +    {
> +      if (so->so_name[0] == '\0')
> +	continue;
> +      if (pattern != NULL && !re_exec (so->so_name))
> +	continue;
> +
> +      struct cleanup *tuple_clean_up
> +        = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
> +      mi_output_solib_attribs (uiout, so);
> +
> +      do_cleanups (tuple_clean_up);
> +    }
> +
> +  do_cleanups (cleanup);
> +}
> diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
> index abb70bd..b7494ce 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 d0906e6..fcadfff 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/mi/mi-interp.c b/gdb/mi/mi-interp.c
> index aa76989..1a26818 100644
> --- a/gdb/mi/mi-interp.c
> +++ b/gdb/mi/mi-interp.c
> @@ -1119,6 +1119,33 @@ mi_on_resume (ptid_t ptid)
>       }
>   }
>   
> +/* See mi-interp.h.  */
> +
> +void
> +mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
> +{
> +  struct gdbarch *gdbarch = target_gdbarch ();
> +
> +  uiout->field_string ("id", solib->so_original_name);
> +  uiout->field_string ("target-name", solib->so_original_name);
> +  uiout->field_string ("host-name", solib->so_name);
> +  uiout->field_int ("symbols-loaded", solib->symbols_loaded);
> +  if (!gdbarch_has_global_solist (target_gdbarch ()))
> +      uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
> +
> +  struct cleanup *cleanup
> +    = make_cleanup_ui_out_list_begin_end (uiout, "ranges");
> +  struct cleanup *tuple_clean_up
> +    = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
> +  if (solib->addr_high != 0)
> +    {
> +      uiout->field_core_addr ("from", gdbarch, solib->addr_low);
> +      uiout->field_core_addr ("to", gdbarch, solib->addr_high);
> +    }
> +  do_cleanups (tuple_clean_up);
> +  do_cleanups (cleanup);
> +}
> +
>   static void
>   mi_solib_loaded (struct so_list *solib)
>   {
> @@ -1140,14 +1167,7 @@ mi_solib_loaded (struct so_list *solib)
>   
>         uiout->redirect (mi->event_channel);
>   
> -      uiout->field_string ("id", solib->so_original_name);
> -      uiout->field_string ("target-name", solib->so_original_name);
> -      uiout->field_string ("host-name", solib->so_name);
> -      uiout->field_int ("symbols-loaded", solib->symbols_loaded);
> -      if (!gdbarch_has_global_solist (target_gdbarch ()))
> -	{
> -	  uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
> -	}
> +      mi_output_solib_attribs (uiout, solib);
>   
>         uiout->redirect (NULL);
>   
> diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
> new file mode 100644
> index 0000000..5b7b9f2
> --- /dev/null
> +++ b/gdb/mi/mi-interp.h
> @@ -0,0 +1,27 @@
> +/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
> +
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +
> +   This file is part of GDB.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef MI_INTERP_H
> +#define MI_INTERP_H
> +
> +/* Output the shared object attributes to UIOUT.  */
> +
> +void mi_output_solib_attribs (ui_out *uiout, struct so_list *solib);
> +
> +#endif
> diff --git a/gdb/solib.c b/gdb/solib.c
> index 38737b6..af94383 100644
> --- a/gdb/solib.c
> +++ b/gdb/solib.c
> @@ -89,9 +89,6 @@ set_solib_ops (struct gdbarch *gdbarch, const struct target_so_ops *new_ops)
>      configuration needs to call set_solib_ops.  */
>   struct target_so_ops *current_target_so_ops;
>   
> -/* List of known shared objects */
> -#define so_list_head current_program_space->so_list
> -
>   /* Local function prototypes */
>   
>   /* If non-empty, this is a search path for loading non-absolute shared library
> @@ -749,21 +746,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)
> @@ -1105,7 +1088,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
>   
>     uiout->table_body ();
>   
> -  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 1b46849..e91fb75 100644
> --- a/gdb/solib.h
> +++ b/gdb/solib.h
> @@ -28,6 +28,9 @@ struct program_space;
>   
>   #include "symfile-add-flags.h"
>   
> +/* List of known shared objects */
> +#define so_list_head current_program_space->so_list
> +
>   /* Called when we free all symtabs, to free the shared library information
>      as well.  */
>   
> @@ -75,6 +78,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 9c7e965..6e2ab66 100644
> --- a/gdb/solist.h
> +++ b/gdb/solist.h
> @@ -24,6 +24,11 @@
>   #include "symtab.h"
>   #include "gdb_bfd.h"
>   
> +#define ALL_SO_LIBS(so) \
> +    for (so = so_list_head; \
> +	 so != NULL; \
> +	 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;
> @@ -74,7 +79,10 @@ struct so_list
>   
>       /* Record the range of addresses belonging to this shared library.
>          There may not be just one (e.g. if two segments are relocated
> -       differently); but this is only used for "info sharedlibrary".  */
> +       differently).  This is used for "info sharedlibrary" and
> +       the MI command "-file-list-shared-libraries".  The later has a format
> +       that supports outputting multiple segments once the related code
> +       supports them.  */
>       CORE_ADDR addr_low, addr_high;
>     };
>   
> diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp
> index 575cb97..ff933e7 100644
> --- a/gdb/testsuite/gdb.mi/mi-solib.exp
> +++ b/gdb/testsuite/gdb.mi/mi-solib.exp
> @@ -48,27 +48,46 @@ 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_with_prefix 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_with_prefix 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=\\\[\{id=\".*${libname}.so\",target-name=\".*${libname}.so\",host-name=\".*${libname}.so\",symbols-loaded=\"1\",thread-group=\".*\",ranges=\\\[\{from=\".*\",to=\".*\"\}]\}]" \
> +	"get the list of shared libraries"
>   }
>   
> -mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
> +test_stop_on_solib_events
> +test_file_list_shared_libraries

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Patch v3] Add -file-list-shared-libraries MI command
  2017-02-28 22:08       ` [Patch v3] " Marc-Andre Laperle
  2017-03-01 15:50         ` Marc-André Laperle
@ 2017-03-01 16:12         ` Eli Zaretskii
  2017-03-01 16:38           ` [Patch v4] " Marc-Andre Laperle
  1 sibling, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2017-03-01 16:12 UTC (permalink / raw)
  To: Marc-Andre Laperle; +Cc: gdb-patches

> From: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
> CC: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
> Date: Tue, 28 Feb 2017 17:07:29 -0500
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 21e8cd3..a5c5e0d 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -68,6 +68,10 @@ flash-erase
>    Erases all the flash memory regions reported by the target.  This is
>    equivalent to the CLI command flash-erase.
>  
> +-file-list-shared-libraries
> +  List the shared libraries in the program.  This is
> +  equivalent to the CLI command "info shared".
> +
>  *** Changes in GDB 7.12

This part is OK.

> -The corresponding @value{GDBN} command is @samp{info shared}.
> +The corresponding @value{GDBN} command is @samp{info shared}. The fields
                                                               ^^
Two spaces there.

> +have a similar meaning than the @code{=library-loaded} notification.

"... a similar meaning to the @code{=library-loaded} notification"

The patch for the manual is OK with these fixed.

Thanks.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [Patch v4] Add -file-list-shared-libraries MI command
  2017-03-01 16:12         ` Eli Zaretskii
@ 2017-03-01 16:38           ` Marc-Andre Laperle
  2017-03-01 17:09             ` Eli Zaretskii
  0 siblings, 1 reply; 26+ messages in thread
From: Marc-Andre Laperle @ 2017-03-01 16:38 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

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/MI Async Records): Update documentation of library-loaded with new
        field.

gdb/ChangeLog:

        * NEWS: Add an entry about new '-file-list-shared-libraries' command.
        * 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.
        * mi/mi-interp.c (mi_output_solib_attribs): New Function.
        * mi/mi-interp.h: New file.
        * solib.c (info_sharedlibrary_command): Replace for loop with
        ALL_SO_LIBS macro
        * solib.h (update_solib_list): New function declaration.
        (so_list_head): Move macro.
        * 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/NEWS                          |  4 +++
 gdb/doc/gdb.texinfo               | 34 ++++++++++++++++++-----
 gdb/mi/mi-cmd-file.c              | 57 +++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-cmds.c                  |  2 ++
 gdb/mi/mi-cmds.h                  |  1 +
 gdb/mi/mi-interp.c                | 36 +++++++++++++++++++------
 gdb/mi/mi-interp.h                | 27 +++++++++++++++++++
 gdb/solib.c                       | 21 ++-------------
 gdb/solib.h                       | 21 +++++++++++++++
 gdb/solist.h                      | 10 ++++++-
 gdb/testsuite/gdb.mi/mi-solib.exp | 49 ++++++++++++++++++++++-----------
 11 files changed, 212 insertions(+), 50 deletions(-)
 create mode 100644 gdb/mi/mi-interp.h

diff --git a/gdb/NEWS b/gdb/NEWS
index 21e8cd3..a5c5e0d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -68,6 +68,10 @@ flash-erase
   Erases all the flash memory regions reported by the target.  This is
   equivalent to the CLI command flash-erase.
 
+-file-list-shared-libraries
+  List the shared libraries in the program.  This is
+  equivalent to the CLI command "info shared".
+
 *** Changes in GDB 7.12
 
 * GDB and GDBserver now build with a C++ compiler by default.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index b9b4c82..f9c0ef8 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -26545,8 +26545,8 @@ 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
+notification has 5 fields---@var{id}, @var{target-name},
+@var{host-name}, @var{symbols-loaded} and @var{ranges}.  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
@@ -26556,7 +26556,8 @@ and should not be relied on to convey any useful information.  The
 @var{thread-group} field, if present, specifies the id of the thread
 group in whose context the library was loaded.  If the field is
 absent, it means the library was loaded in the context of all present
-thread groups.
+thread groups. The @var{ranges} field specifies the ranges of addresses belonging
+to this library.
 
 @item =library-unloaded,...
 Reports that a library was unloaded by the program.  This notification
@@ -31477,26 +31478,45 @@ 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}.
+The corresponding @value{GDBN} command is @samp{info shared}.  The fields
+have a similar meaning to the @code{=library-loaded} notification.
+The @code{ranges} field specifies the muliple segments belonging to this
+library.  Each range has the following fields:
+
+@table @samp
+@item from
+The address defining the inclusive lower bound of the segment.
+@item to
+The address defining the exclusive upper bound of the segment.
+@end table
 
 @subsubheading Example
-N.A.
+@smallexample
+(gdb)
+-file-list-exec-source-files
+^done,shared-libraries=[
+@{id="/lib/libfoo.so",target-name="/lib/libfoo.so",host-name="/lib/libfoo.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x72815989",to="0x728162c0"@}]@},
+@{id="/lib/libbar.so",target-name="/lib/libbar.so",host-name="/lib/libbar.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x76ee48c0",to="0x76ee9160"@}]@}]
+(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 71e2845..a2ad392 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -20,11 +20,15 @@
 #include "defs.h"
 #include "mi-cmds.h"
 #include "mi-getopt.h"
+#include "mi-interp.h"
 #include "ui-out.h"
 #include "symtab.h"
 #include "source.h"
 #include "objfiles.h"
 #include "psymtab.h"
+#include "solib.h"
+#include "solist.h"
+#include "gdb_regex.h"
 
 /* Return to the client the absolute path and line number of the 
    current file being executed.  */
@@ -106,3 +110,56 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
 
   uiout->end (ui_out_type_list);
 }
+
+/* See mi-cmds.h.  */
+
+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]"));
+    }
+
+  if (pattern != NULL)
+    {
+      const char *re_err = re_comp (pattern);
+
+      if (re_err != NULL)
+	error (_("Invalid regexp: %s"), re_err);
+    }
+
+  update_solib_list (1);
+
+  /* Print the table header.  */
+  struct cleanup *cleanup
+    = make_cleanup_ui_out_list_begin_end (uiout, "shared-libraries");
+
+  ALL_SO_LIBS (so)
+    {
+      if (so->so_name[0] == '\0')
+	continue;
+      if (pattern != NULL && !re_exec (so->so_name))
+	continue;
+
+      struct cleanup *tuple_clean_up
+        = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+      mi_output_solib_attribs (uiout, so);
+
+      do_cleanups (tuple_clean_up);
+    }
+
+  do_cleanups (cleanup);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index abb70bd..b7494ce 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 d0906e6..fcadfff 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/mi/mi-interp.c b/gdb/mi/mi-interp.c
index aa76989..1a26818 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1119,6 +1119,33 @@ mi_on_resume (ptid_t ptid)
     }
 }
 
+/* See mi-interp.h.  */
+
+void
+mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
+{
+  struct gdbarch *gdbarch = target_gdbarch ();
+
+  uiout->field_string ("id", solib->so_original_name);
+  uiout->field_string ("target-name", solib->so_original_name);
+  uiout->field_string ("host-name", solib->so_name);
+  uiout->field_int ("symbols-loaded", solib->symbols_loaded);
+  if (!gdbarch_has_global_solist (target_gdbarch ()))
+      uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
+
+  struct cleanup *cleanup
+    = make_cleanup_ui_out_list_begin_end (uiout, "ranges");
+  struct cleanup *tuple_clean_up
+    = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+  if (solib->addr_high != 0)
+    {
+      uiout->field_core_addr ("from", gdbarch, solib->addr_low);
+      uiout->field_core_addr ("to", gdbarch, solib->addr_high);
+    }
+  do_cleanups (tuple_clean_up);
+  do_cleanups (cleanup);
+}
+
 static void
 mi_solib_loaded (struct so_list *solib)
 {
@@ -1140,14 +1167,7 @@ mi_solib_loaded (struct so_list *solib)
 
       uiout->redirect (mi->event_channel);
 
-      uiout->field_string ("id", solib->so_original_name);
-      uiout->field_string ("target-name", solib->so_original_name);
-      uiout->field_string ("host-name", solib->so_name);
-      uiout->field_int ("symbols-loaded", solib->symbols_loaded);
-      if (!gdbarch_has_global_solist (target_gdbarch ()))
-	{
-	  uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
-	}
+      mi_output_solib_attribs (uiout, solib);
 
       uiout->redirect (NULL);
 
diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
new file mode 100644
index 0000000..5b7b9f2
--- /dev/null
+++ b/gdb/mi/mi-interp.h
@@ -0,0 +1,27 @@
+/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef MI_INTERP_H
+#define MI_INTERP_H
+
+/* Output the shared object attributes to UIOUT.  */
+
+void mi_output_solib_attribs (ui_out *uiout, struct so_list *solib);
+
+#endif
diff --git a/gdb/solib.c b/gdb/solib.c
index 38737b6..af94383 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -89,9 +89,6 @@ set_solib_ops (struct gdbarch *gdbarch, const struct target_so_ops *new_ops)
    configuration needs to call set_solib_ops.  */
 struct target_so_ops *current_target_so_ops;
 
-/* List of known shared objects */
-#define so_list_head current_program_space->so_list
-
 /* Local function prototypes */
 
 /* If non-empty, this is a search path for loading non-absolute shared library
@@ -749,21 +746,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)
@@ -1105,7 +1088,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
 
   uiout->table_body ();
 
-  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 1b46849..e91fb75 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -28,6 +28,9 @@ struct program_space;
 
 #include "symfile-add-flags.h"
 
+/* List of known shared objects */
+#define so_list_head current_program_space->so_list
+
 /* Called when we free all symtabs, to free the shared library information
    as well.  */
 
@@ -75,6 +78,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 9c7e965..6e2ab66 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -24,6 +24,11 @@
 #include "symtab.h"
 #include "gdb_bfd.h"
 
+#define ALL_SO_LIBS(so) \
+    for (so = so_list_head; \
+	 so != NULL; \
+	 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;
@@ -74,7 +79,10 @@ struct so_list
 
     /* Record the range of addresses belonging to this shared library.
        There may not be just one (e.g. if two segments are relocated
-       differently); but this is only used for "info sharedlibrary".  */
+       differently).  This is used for "info sharedlibrary" and
+       the MI command "-file-list-shared-libraries".  The later has a format
+       that supports outputting multiple segments once the related code
+       supports them.  */
     CORE_ADDR addr_low, addr_high;
   };
 
diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp
index 575cb97..ff933e7 100644
--- a/gdb/testsuite/gdb.mi/mi-solib.exp
+++ b/gdb/testsuite/gdb.mi/mi-solib.exp
@@ -48,27 +48,46 @@ 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_with_prefix 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_with_prefix 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=\\\[\{id=\".*${libname}.so\",target-name=\".*${libname}.so\",host-name=\".*${libname}.so\",symbols-loaded=\"1\",thread-group=\".*\",ranges=\\\[\{from=\".*\",to=\".*\"\}]\}]" \
+	"get the list of shared libraries"
 }
 
-mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
+test_stop_on_solib_events
+test_file_list_shared_libraries
-- 
2.9.3

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Patch v4] Add -file-list-shared-libraries MI command
  2017-03-01 16:38           ` [Patch v4] " Marc-Andre Laperle
@ 2017-03-01 17:09             ` Eli Zaretskii
  2017-03-02 14:56               ` [Patch v5] " Marc-Andre Laperle
  0 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2017-03-01 17:09 UTC (permalink / raw)
  To: Marc-Andre Laperle; +Cc: gdb-patches

> From: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
> CC: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
> Date: Wed, 1 Mar 2017 11:37:18 -0500
> 
> -thread groups.
> +thread groups. The @var{ranges} field specifies the ranges of addresses belonging
                ^^
Two spaces there.

> +to this library.

Otherwise the documentation parts are OK.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [Patch v5] Add -file-list-shared-libraries MI command
  2017-03-01 17:09             ` Eli Zaretskii
@ 2017-03-02 14:56               ` Marc-Andre Laperle
  2017-03-09 19:12                 ` Marc-André Laperle
  2017-03-17 16:55                 ` Pedro Alves
  0 siblings, 2 replies; 26+ messages in thread
From: Marc-Andre Laperle @ 2017-03-02 14:56 UTC (permalink / raw)
  To: gdb-patches; +Cc: Marc-Andre Laperle

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/MI Async Records): Update documentation of library-loaded with new
        field.

gdb/ChangeLog:

        * NEWS: Add an entry about new '-file-list-shared-libraries' command.
        * 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.
        * mi/mi-interp.c (mi_output_solib_attribs): New Function.
        * mi/mi-interp.h: New file.
        * solib.c (info_sharedlibrary_command): Replace for loop with
        ALL_SO_LIBS macro
        * solib.h (update_solib_list): New function declaration.
        (so_list_head): Move macro.
        * 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/NEWS                          |  4 +++
 gdb/doc/gdb.texinfo               | 34 ++++++++++++++++++-----
 gdb/mi/mi-cmd-file.c              | 57 +++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-cmds.c                  |  2 ++
 gdb/mi/mi-cmds.h                  |  1 +
 gdb/mi/mi-interp.c                | 36 +++++++++++++++++++------
 gdb/mi/mi-interp.h                | 27 +++++++++++++++++++
 gdb/solib.c                       | 21 ++-------------
 gdb/solib.h                       | 21 +++++++++++++++
 gdb/solist.h                      | 10 ++++++-
 gdb/testsuite/gdb.mi/mi-solib.exp | 49 ++++++++++++++++++++++-----------
 11 files changed, 212 insertions(+), 50 deletions(-)
 create mode 100644 gdb/mi/mi-interp.h

diff --git a/gdb/NEWS b/gdb/NEWS
index 21e8cd3..a5c5e0d 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -68,6 +68,10 @@ flash-erase
   Erases all the flash memory regions reported by the target.  This is
   equivalent to the CLI command flash-erase.
 
+-file-list-shared-libraries
+  List the shared libraries in the program.  This is
+  equivalent to the CLI command "info shared".
+
 *** Changes in GDB 7.12
 
 * GDB and GDBserver now build with a C++ compiler by default.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index b9b4c82..4d68984 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -26545,8 +26545,8 @@ 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
+notification has 5 fields---@var{id}, @var{target-name},
+@var{host-name}, @var{symbols-loaded} and @var{ranges}.  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
@@ -26556,7 +26556,8 @@ and should not be relied on to convey any useful information.  The
 @var{thread-group} field, if present, specifies the id of the thread
 group in whose context the library was loaded.  If the field is
 absent, it means the library was loaded in the context of all present
-thread groups.
+thread groups.  The @var{ranges} field specifies the ranges of addresses belonging
+to this library.
 
 @item =library-unloaded,...
 Reports that a library was unloaded by the program.  This notification
@@ -31477,26 +31478,45 @@ 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}.
+The corresponding @value{GDBN} command is @samp{info shared}.  The fields
+have a similar meaning to the @code{=library-loaded} notification.
+The @code{ranges} field specifies the muliple segments belonging to this
+library.  Each range has the following fields:
+
+@table @samp
+@item from
+The address defining the inclusive lower bound of the segment.
+@item to
+The address defining the exclusive upper bound of the segment.
+@end table
 
 @subsubheading Example
-N.A.
+@smallexample
+(gdb)
+-file-list-exec-source-files
+^done,shared-libraries=[
+@{id="/lib/libfoo.so",target-name="/lib/libfoo.so",host-name="/lib/libfoo.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x72815989",to="0x728162c0"@}]@},
+@{id="/lib/libbar.so",target-name="/lib/libbar.so",host-name="/lib/libbar.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x76ee48c0",to="0x76ee9160"@}]@}]
+(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 71e2845..a2ad392 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -20,11 +20,15 @@
 #include "defs.h"
 #include "mi-cmds.h"
 #include "mi-getopt.h"
+#include "mi-interp.h"
 #include "ui-out.h"
 #include "symtab.h"
 #include "source.h"
 #include "objfiles.h"
 #include "psymtab.h"
+#include "solib.h"
+#include "solist.h"
+#include "gdb_regex.h"
 
 /* Return to the client the absolute path and line number of the 
    current file being executed.  */
@@ -106,3 +110,56 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
 
   uiout->end (ui_out_type_list);
 }
+
+/* See mi-cmds.h.  */
+
+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]"));
+    }
+
+  if (pattern != NULL)
+    {
+      const char *re_err = re_comp (pattern);
+
+      if (re_err != NULL)
+	error (_("Invalid regexp: %s"), re_err);
+    }
+
+  update_solib_list (1);
+
+  /* Print the table header.  */
+  struct cleanup *cleanup
+    = make_cleanup_ui_out_list_begin_end (uiout, "shared-libraries");
+
+  ALL_SO_LIBS (so)
+    {
+      if (so->so_name[0] == '\0')
+	continue;
+      if (pattern != NULL && !re_exec (so->so_name))
+	continue;
+
+      struct cleanup *tuple_clean_up
+        = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+      mi_output_solib_attribs (uiout, so);
+
+      do_cleanups (tuple_clean_up);
+    }
+
+  do_cleanups (cleanup);
+}
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index abb70bd..b7494ce 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 d0906e6..fcadfff 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/mi/mi-interp.c b/gdb/mi/mi-interp.c
index aa76989..1a26818 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -1119,6 +1119,33 @@ mi_on_resume (ptid_t ptid)
     }
 }
 
+/* See mi-interp.h.  */
+
+void
+mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
+{
+  struct gdbarch *gdbarch = target_gdbarch ();
+
+  uiout->field_string ("id", solib->so_original_name);
+  uiout->field_string ("target-name", solib->so_original_name);
+  uiout->field_string ("host-name", solib->so_name);
+  uiout->field_int ("symbols-loaded", solib->symbols_loaded);
+  if (!gdbarch_has_global_solist (target_gdbarch ()))
+      uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
+
+  struct cleanup *cleanup
+    = make_cleanup_ui_out_list_begin_end (uiout, "ranges");
+  struct cleanup *tuple_clean_up
+    = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+  if (solib->addr_high != 0)
+    {
+      uiout->field_core_addr ("from", gdbarch, solib->addr_low);
+      uiout->field_core_addr ("to", gdbarch, solib->addr_high);
+    }
+  do_cleanups (tuple_clean_up);
+  do_cleanups (cleanup);
+}
+
 static void
 mi_solib_loaded (struct so_list *solib)
 {
@@ -1140,14 +1167,7 @@ mi_solib_loaded (struct so_list *solib)
 
       uiout->redirect (mi->event_channel);
 
-      uiout->field_string ("id", solib->so_original_name);
-      uiout->field_string ("target-name", solib->so_original_name);
-      uiout->field_string ("host-name", solib->so_name);
-      uiout->field_int ("symbols-loaded", solib->symbols_loaded);
-      if (!gdbarch_has_global_solist (target_gdbarch ()))
-	{
-	  uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
-	}
+      mi_output_solib_attribs (uiout, solib);
 
       uiout->redirect (NULL);
 
diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
new file mode 100644
index 0000000..5b7b9f2
--- /dev/null
+++ b/gdb/mi/mi-interp.h
@@ -0,0 +1,27 @@
+/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef MI_INTERP_H
+#define MI_INTERP_H
+
+/* Output the shared object attributes to UIOUT.  */
+
+void mi_output_solib_attribs (ui_out *uiout, struct so_list *solib);
+
+#endif
diff --git a/gdb/solib.c b/gdb/solib.c
index 38737b6..af94383 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -89,9 +89,6 @@ set_solib_ops (struct gdbarch *gdbarch, const struct target_so_ops *new_ops)
    configuration needs to call set_solib_ops.  */
 struct target_so_ops *current_target_so_ops;
 
-/* List of known shared objects */
-#define so_list_head current_program_space->so_list
-
 /* Local function prototypes */
 
 /* If non-empty, this is a search path for loading non-absolute shared library
@@ -749,21 +746,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)
@@ -1105,7 +1088,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
 
   uiout->table_body ();
 
-  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 1b46849..e91fb75 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -28,6 +28,9 @@ struct program_space;
 
 #include "symfile-add-flags.h"
 
+/* List of known shared objects */
+#define so_list_head current_program_space->so_list
+
 /* Called when we free all symtabs, to free the shared library information
    as well.  */
 
@@ -75,6 +78,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 9c7e965..6e2ab66 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -24,6 +24,11 @@
 #include "symtab.h"
 #include "gdb_bfd.h"
 
+#define ALL_SO_LIBS(so) \
+    for (so = so_list_head; \
+	 so != NULL; \
+	 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;
@@ -74,7 +79,10 @@ struct so_list
 
     /* Record the range of addresses belonging to this shared library.
        There may not be just one (e.g. if two segments are relocated
-       differently); but this is only used for "info sharedlibrary".  */
+       differently).  This is used for "info sharedlibrary" and
+       the MI command "-file-list-shared-libraries".  The later has a format
+       that supports outputting multiple segments once the related code
+       supports them.  */
     CORE_ADDR addr_low, addr_high;
   };
 
diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp
index 575cb97..ff933e7 100644
--- a/gdb/testsuite/gdb.mi/mi-solib.exp
+++ b/gdb/testsuite/gdb.mi/mi-solib.exp
@@ -48,27 +48,46 @@ 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_with_prefix 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_with_prefix 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=\\\[\{id=\".*${libname}.so\",target-name=\".*${libname}.so\",host-name=\".*${libname}.so\",symbols-loaded=\"1\",thread-group=\".*\",ranges=\\\[\{from=\".*\",to=\".*\"\}]\}]" \
+	"get the list of shared libraries"
 }
 
-mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
+test_stop_on_solib_events
+test_file_list_shared_libraries
-- 
2.9.3

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Patch v5] Add -file-list-shared-libraries MI command
  2017-03-02 14:56               ` [Patch v5] " Marc-Andre Laperle
@ 2017-03-09 19:12                 ` Marc-André Laperle
  2017-03-17 16:55                 ` Pedro Alves
  1 sibling, 0 replies; 26+ messages in thread
From: Marc-André Laperle @ 2017-03-09 19:12 UTC (permalink / raw)
  To: gdb-patches

Any chance that this can make it in before the branching? :)

Thanks!
Marc-André

On 2017-03-02 09:55 AM, Marc-Andre Laperle wrote:
> 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/MI Async Records): Update documentation of library-loaded with new
>          field.
>
> gdb/ChangeLog:
>
>          * NEWS: Add an entry about new '-file-list-shared-libraries' command.
>          * 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.
>          * mi/mi-interp.c (mi_output_solib_attribs): New Function.
>          * mi/mi-interp.h: New file.
>          * solib.c (info_sharedlibrary_command): Replace for loop with
>          ALL_SO_LIBS macro
>          * solib.h (update_solib_list): New function declaration.
>          (so_list_head): Move macro.
>          * 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/NEWS                          |  4 +++
>   gdb/doc/gdb.texinfo               | 34 ++++++++++++++++++-----
>   gdb/mi/mi-cmd-file.c              | 57 +++++++++++++++++++++++++++++++++++++++
>   gdb/mi/mi-cmds.c                  |  2 ++
>   gdb/mi/mi-cmds.h                  |  1 +
>   gdb/mi/mi-interp.c                | 36 +++++++++++++++++++------
>   gdb/mi/mi-interp.h                | 27 +++++++++++++++++++
>   gdb/solib.c                       | 21 ++-------------
>   gdb/solib.h                       | 21 +++++++++++++++
>   gdb/solist.h                      | 10 ++++++-
>   gdb/testsuite/gdb.mi/mi-solib.exp | 49 ++++++++++++++++++++++-----------
>   11 files changed, 212 insertions(+), 50 deletions(-)
>   create mode 100644 gdb/mi/mi-interp.h
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 21e8cd3..a5c5e0d 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -68,6 +68,10 @@ flash-erase
>     Erases all the flash memory regions reported by the target.  This is
>     equivalent to the CLI command flash-erase.
>   
> +-file-list-shared-libraries
> +  List the shared libraries in the program.  This is
> +  equivalent to the CLI command "info shared".
> +
>   *** Changes in GDB 7.12
>   
>   * GDB and GDBserver now build with a C++ compiler by default.
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index b9b4c82..4d68984 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -26545,8 +26545,8 @@ 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
> +notification has 5 fields---@var{id}, @var{target-name},
> +@var{host-name}, @var{symbols-loaded} and @var{ranges}.  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
> @@ -26556,7 +26556,8 @@ and should not be relied on to convey any useful information.  The
>   @var{thread-group} field, if present, specifies the id of the thread
>   group in whose context the library was loaded.  If the field is
>   absent, it means the library was loaded in the context of all present
> -thread groups.
> +thread groups.  The @var{ranges} field specifies the ranges of addresses belonging
> +to this library.
>   
>   @item =library-unloaded,...
>   Reports that a library was unloaded by the program.  This notification
> @@ -31477,26 +31478,45 @@ 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}.
> +The corresponding @value{GDBN} command is @samp{info shared}.  The fields
> +have a similar meaning to the @code{=library-loaded} notification.
> +The @code{ranges} field specifies the muliple segments belonging to this
> +library.  Each range has the following fields:
> +
> +@table @samp
> +@item from
> +The address defining the inclusive lower bound of the segment.
> +@item to
> +The address defining the exclusive upper bound of the segment.
> +@end table
>   
>   @subsubheading Example
> -N.A.
> +@smallexample
> +(gdb)
> +-file-list-exec-source-files
> +^done,shared-libraries=[
> +@{id="/lib/libfoo.so",target-name="/lib/libfoo.so",host-name="/lib/libfoo.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x72815989",to="0x728162c0"@}]@},
> +@{id="/lib/libbar.so",target-name="/lib/libbar.so",host-name="/lib/libbar.so",symbols-loaded="1",thread-group="i1",ranges=[@{from="0x76ee48c0",to="0x76ee9160"@}]@}]
> +(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 71e2845..a2ad392 100644
> --- a/gdb/mi/mi-cmd-file.c
> +++ b/gdb/mi/mi-cmd-file.c
> @@ -20,11 +20,15 @@
>   #include "defs.h"
>   #include "mi-cmds.h"
>   #include "mi-getopt.h"
> +#include "mi-interp.h"
>   #include "ui-out.h"
>   #include "symtab.h"
>   #include "source.h"
>   #include "objfiles.h"
>   #include "psymtab.h"
> +#include "solib.h"
> +#include "solist.h"
> +#include "gdb_regex.h"
>   
>   /* Return to the client the absolute path and line number of the
>      current file being executed.  */
> @@ -106,3 +110,56 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
>   
>     uiout->end (ui_out_type_list);
>   }
> +
> +/* See mi-cmds.h.  */
> +
> +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]"));
> +    }
> +
> +  if (pattern != NULL)
> +    {
> +      const char *re_err = re_comp (pattern);
> +
> +      if (re_err != NULL)
> +	error (_("Invalid regexp: %s"), re_err);
> +    }
> +
> +  update_solib_list (1);
> +
> +  /* Print the table header.  */
> +  struct cleanup *cleanup
> +    = make_cleanup_ui_out_list_begin_end (uiout, "shared-libraries");
> +
> +  ALL_SO_LIBS (so)
> +    {
> +      if (so->so_name[0] == '\0')
> +	continue;
> +      if (pattern != NULL && !re_exec (so->so_name))
> +	continue;
> +
> +      struct cleanup *tuple_clean_up
> +        = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
> +      mi_output_solib_attribs (uiout, so);
> +
> +      do_cleanups (tuple_clean_up);
> +    }
> +
> +  do_cleanups (cleanup);
> +}
> diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
> index abb70bd..b7494ce 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 d0906e6..fcadfff 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/mi/mi-interp.c b/gdb/mi/mi-interp.c
> index aa76989..1a26818 100644
> --- a/gdb/mi/mi-interp.c
> +++ b/gdb/mi/mi-interp.c
> @@ -1119,6 +1119,33 @@ mi_on_resume (ptid_t ptid)
>       }
>   }
>   
> +/* See mi-interp.h.  */
> +
> +void
> +mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
> +{
> +  struct gdbarch *gdbarch = target_gdbarch ();
> +
> +  uiout->field_string ("id", solib->so_original_name);
> +  uiout->field_string ("target-name", solib->so_original_name);
> +  uiout->field_string ("host-name", solib->so_name);
> +  uiout->field_int ("symbols-loaded", solib->symbols_loaded);
> +  if (!gdbarch_has_global_solist (target_gdbarch ()))
> +      uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
> +
> +  struct cleanup *cleanup
> +    = make_cleanup_ui_out_list_begin_end (uiout, "ranges");
> +  struct cleanup *tuple_clean_up
> +    = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
> +  if (solib->addr_high != 0)
> +    {
> +      uiout->field_core_addr ("from", gdbarch, solib->addr_low);
> +      uiout->field_core_addr ("to", gdbarch, solib->addr_high);
> +    }
> +  do_cleanups (tuple_clean_up);
> +  do_cleanups (cleanup);
> +}
> +
>   static void
>   mi_solib_loaded (struct so_list *solib)
>   {
> @@ -1140,14 +1167,7 @@ mi_solib_loaded (struct so_list *solib)
>   
>         uiout->redirect (mi->event_channel);
>   
> -      uiout->field_string ("id", solib->so_original_name);
> -      uiout->field_string ("target-name", solib->so_original_name);
> -      uiout->field_string ("host-name", solib->so_name);
> -      uiout->field_int ("symbols-loaded", solib->symbols_loaded);
> -      if (!gdbarch_has_global_solist (target_gdbarch ()))
> -	{
> -	  uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
> -	}
> +      mi_output_solib_attribs (uiout, solib);
>   
>         uiout->redirect (NULL);
>   
> diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
> new file mode 100644
> index 0000000..5b7b9f2
> --- /dev/null
> +++ b/gdb/mi/mi-interp.h
> @@ -0,0 +1,27 @@
> +/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
> +
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +
> +   This file is part of GDB.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef MI_INTERP_H
> +#define MI_INTERP_H
> +
> +/* Output the shared object attributes to UIOUT.  */
> +
> +void mi_output_solib_attribs (ui_out *uiout, struct so_list *solib);
> +
> +#endif
> diff --git a/gdb/solib.c b/gdb/solib.c
> index 38737b6..af94383 100644
> --- a/gdb/solib.c
> +++ b/gdb/solib.c
> @@ -89,9 +89,6 @@ set_solib_ops (struct gdbarch *gdbarch, const struct target_so_ops *new_ops)
>      configuration needs to call set_solib_ops.  */
>   struct target_so_ops *current_target_so_ops;
>   
> -/* List of known shared objects */
> -#define so_list_head current_program_space->so_list
> -
>   /* Local function prototypes */
>   
>   /* If non-empty, this is a search path for loading non-absolute shared library
> @@ -749,21 +746,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)
> @@ -1105,7 +1088,7 @@ info_sharedlibrary_command (char *pattern, int from_tty)
>   
>     uiout->table_body ();
>   
> -  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 1b46849..e91fb75 100644
> --- a/gdb/solib.h
> +++ b/gdb/solib.h
> @@ -28,6 +28,9 @@ struct program_space;
>   
>   #include "symfile-add-flags.h"
>   
> +/* List of known shared objects */
> +#define so_list_head current_program_space->so_list
> +
>   /* Called when we free all symtabs, to free the shared library information
>      as well.  */
>   
> @@ -75,6 +78,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 9c7e965..6e2ab66 100644
> --- a/gdb/solist.h
> +++ b/gdb/solist.h
> @@ -24,6 +24,11 @@
>   #include "symtab.h"
>   #include "gdb_bfd.h"
>   
> +#define ALL_SO_LIBS(so) \
> +    for (so = so_list_head; \
> +	 so != NULL; \
> +	 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;
> @@ -74,7 +79,10 @@ struct so_list
>   
>       /* Record the range of addresses belonging to this shared library.
>          There may not be just one (e.g. if two segments are relocated
> -       differently); but this is only used for "info sharedlibrary".  */
> +       differently).  This is used for "info sharedlibrary" and
> +       the MI command "-file-list-shared-libraries".  The later has a format
> +       that supports outputting multiple segments once the related code
> +       supports them.  */
>       CORE_ADDR addr_low, addr_high;
>     };
>   
> diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp
> index 575cb97..ff933e7 100644
> --- a/gdb/testsuite/gdb.mi/mi-solib.exp
> +++ b/gdb/testsuite/gdb.mi/mi-solib.exp
> @@ -48,27 +48,46 @@ 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_with_prefix 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_with_prefix 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=\\\[\{id=\".*${libname}.so\",target-name=\".*${libname}.so\",host-name=\".*${libname}.so\",symbols-loaded=\"1\",thread-group=\".*\",ranges=\\\[\{from=\".*\",to=\".*\"\}]\}]" \
> +	"get the list of shared libraries"
>   }
>   
> -mi_expect_stop solib-event .* .* .* .* .* "check for solib event"
> +test_stop_on_solib_events
> +test_file_list_shared_libraries

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Patch v5] Add -file-list-shared-libraries MI command
  2017-03-02 14:56               ` [Patch v5] " Marc-Andre Laperle
  2017-03-09 19:12                 ` Marc-André Laperle
@ 2017-03-17 16:55                 ` Pedro Alves
  2017-03-20 19:07                   ` Marc-André Laperle
  1 sibling, 1 reply; 26+ messages in thread
From: Pedro Alves @ 2017-03-17 16:55 UTC (permalink / raw)
  To: Marc-Andre Laperle, gdb-patches

On 03/02/2017 02:55 PM, Marc-Andre Laperle wrote:

> -The corresponding @value{GDBN} command is @samp{info shared}.
> +The corresponding @value{GDBN} command is @samp{info shared}.  The fields
> +have a similar meaning to the @code{=library-loaded} notification.
> +The @code{ranges} field specifies the muliple segments belonging to this

Typo "muliple".

>      /* Record the range of addresses belonging to this shared library.
>         There may not be just one (e.g. if two segments are relocated
> -       differently); but this is only used for "info sharedlibrary".  */
> +       differently).  This is used for "info sharedlibrary" and
> +       the MI command "-file-list-shared-libraries".  The later has a format

Typo: "latter".

> +       that supports outputting multiple segments once the related code
> +       supports them.  */
>      CORE_ADDR addr_low, addr_high;
>    };
>  

Fix those, and you're good to go.  Please push.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Patch v5] Add -file-list-shared-libraries MI command
  2017-03-17 16:55                 ` Pedro Alves
@ 2017-03-20 19:07                   ` Marc-André Laperle
  0 siblings, 0 replies; 26+ messages in thread
From: Marc-André Laperle @ 2017-03-20 19:07 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

Thank you. Pushed with the typo fixed.

Marc-André

From: gdb-patches-owner@sourceware.org <gdb-patches-owner@sourceware.org> on behalf of Pedro Alves <palves@redhat.com>
Sent: Friday, March 17, 2017 12:55 PM
To: Marc-André Laperle; gdb-patches@sourceware.org
Subject: Re: [Patch v5] Add -file-list-shared-libraries MI command
    
On 03/02/2017 02:55 PM, Marc-Andre Laperle wrote:

> -The corresponding @value{GDBN} command is @samp{info shared}.
> +The corresponding @value{GDBN} command is @samp{info shared}.  The fields
> +have a similar meaning to the @code{=library-loaded} notification.
> +The @code{ranges} field specifies the muliple segments belonging to this

Typo "muliple".

>      /* Record the range of addresses belonging to this shared library.
>         There may not be just one (e.g. if two segments are relocated
> -       differently); but this is only used for "info sharedlibrary".  */
> +       differently).  This is used for "info sharedlibrary" and
> +       the MI command "-file-list-shared-libraries".  The later has a format

Typo: "latter".

> +       that supports outputting multiple segments once the related code
> +       supports them.  */
>      CORE_ADDR addr_low, addr_high;
>    };
>  

Fix those, and you're good to go.  Please push.

Thanks,
Pedro Alves

    

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2017-03-20 19:07 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-12 20:28 [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
2016-09-12 20:28 ` [PATCH 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle
2016-10-20  4:24   ` Simon Marchi
2016-11-23 13:03   ` Pedro Alves
2016-09-12 20:28 ` [PATCH 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
2016-10-14 21:20   ` Marc-André Laperle
2016-10-20  5:05   ` Simon Marchi
2016-11-23 13:06   ` Pedro Alves
2017-01-04 17:19     ` Marc-André Laperle
2017-01-12 16:15       ` Pedro Alves
2016-10-20  4:20 ` [PATCH 1/3] Remove unused parameter in solib_add and update_solib_list Simon Marchi
2016-11-23 13:03 ` Pedro Alves
2017-02-03 17:17 ` [PATCH v2 0/3] Shared libraries MI command Marc-Andre Laperle
2017-02-03 17:16   ` [PATCH v2 1/3] Remove unused parameter in solib_add and update_solib_list Marc-Andre Laperle
2017-02-03 17:16   ` [PATCH v2 3/3] Add -file-list-shared-libraries MI command Marc-Andre Laperle
2017-02-06 12:40     ` Pedro Alves
2017-02-28 22:08       ` [Patch v3] " Marc-Andre Laperle
2017-03-01 15:50         ` Marc-André Laperle
2017-03-01 16:12         ` Eli Zaretskii
2017-03-01 16:38           ` [Patch v4] " Marc-Andre Laperle
2017-03-01 17:09             ` Eli Zaretskii
2017-03-02 14:56               ` [Patch v5] " Marc-Andre Laperle
2017-03-09 19:12                 ` Marc-André Laperle
2017-03-17 16:55                 ` Pedro Alves
2017-03-20 19:07                   ` Marc-André Laperle
2017-02-03 17:16   ` [PATCH v2 2/3] Add a better diagnostic message in mi_gdb_test Marc-Andre Laperle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).