* [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, ¤t_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, ¤t_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, ¤t_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, ¤t_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
* [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
* 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 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
* [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
* 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 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 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
* 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 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
* [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
* [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, ¤t_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, ¤t_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, ¤t_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, ¤t_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
* 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
* [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
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).