From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11068 invoked by alias); 10 Jan 2011 20:16:08 -0000 Received: (qmail 11044 invoked by uid 22791); 10 Jan 2011 20:16:05 -0000 X-SWARE-Spam-Status: No, hits=-6.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_RG,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 10 Jan 2011 20:15:59 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0AKFwSE029464 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 10 Jan 2011 15:15:58 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p0AKFvwX025829; Mon, 10 Jan 2011 15:15:57 -0500 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p0AKFuTE025883; Mon, 10 Jan 2011 15:15:57 -0500 Received: by opsy.redhat.com (Postfix, from userid 500) id 998AA3784A7; Mon, 10 Jan 2011 13:15:56 -0700 (MST) From: Tom Tromey To: gdb-patches@sourceware.org Subject: RFA: fix PR mi/8138 Date: Mon, 10 Jan 2011 20:16:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-01/txt/msg00202.txt.bz2 This needs at least a doc review. This fixes PR 8138. The bug is that there is no MI equivalent of "info shared". This patch fixes the bug in a reasonably straightforward way. There is a little ugliness in info_sharedlibrary_command, because the MI docs say that new MI commands will always output lists, but this command was emitting a table. Built and regested on x86-64 (compile farm). A new test case is included; this requires my previous patch. Tom 2011-01-10 Tom Tromey PR mi/8138: * solib.h (info_sharedlibrary_command): Declare. * solib.c (info_sharedlibrary_command): No longer 'static'. Handle MI output. * mi/mi-cmds.c (mi_cmds): Add "file-list-shared-libraries" entry. * mi/mi-cmd-file.c (mi_cmd_file_list_shared_libraries): New function. * mi/mi-cmds.h (mi_cmd_file_list_shared_libraries): Declare. 2011-01-10 Tom Tromey * gdb.texinfo (GDB/MI File Commands): Document -file-list-shared-libraries. 2011-01-10 Tom Tromey * gdb.mi/mi-solib.exp: Add test for -file-list-shared-libraries. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 7f8c785..e3a59cd 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -28847,7 +28847,7 @@ The @value{GDBN} equivalent is @samp{info sources}. (gdb) @end smallexample -@ignore + @subheading The @code{-file-list-shared-libraries} Command @findex -file-list-shared-libraries @@ -28859,14 +28859,41 @@ The @value{GDBN} equivalent is @samp{info sources}. List the shared libraries in the program. +@subsubheading Result + +The result is a table of libraries. The following attributes are +defined for a given library: + +@table @samp +@item from +@itemx to +These items, if provided, are a range of addresses belonging to this +shared library. + +@item syms-read +This indicates whether debugging information has been read for this +library. This is either @samp{0}, meaning that debugging information +for this library has not been read; @samp{1}, meaning that the library +does not have debugging information; or @samp{2}, meaning that the +debugging information exists and has been read. + +@item name +The name of the library. +@end table + @subsubheading @value{GDBN} Command The corresponding @value{GDBN} command is @samp{info shared}. @subsubheading Example -N.A. +@smallexample +(gdb) +-file-list-shared-libraries +^done,sharedlibs=[lib=[from="0x00111360",to="0x00111498",syms-read="2",name="/lib/libexample.so"]] +@end smallexample +@ignore @subheading The @code{-file-list-symbol-files} Command @findex -file-list-symbol-files diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c index e575012..b7d0030 100644 --- a/gdb/mi/mi-cmd-file.c +++ b/gdb/mi/mi-cmd-file.c @@ -26,6 +26,7 @@ #include "source.h" #include "objfiles.h" #include "psymtab.h" +#include "solib.h" /* Return to the client the absolute path and line number of the current file being executed. */ @@ -109,3 +110,14 @@ mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc) ui_out_end (uiout, ui_out_type_list); } + +/* Implementation of the -file-list-shared-libraries command. */ + +void +mi_cmd_file_list_shared_libraries (char *command, char **argv, int argc) +{ + if (!mi_valid_noargs ("mi_cmd_file_list_shared_libraries", argc, argv)) + error (_("mi_cmd_file_list_shared_libraries: Usage: No args")); + + info_sharedlibrary_command (NULL, 0); +} diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 0b32db0..3e6da2e 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -82,6 +82,8 @@ struct mi_cmd mi_cmds[] = mi_cmd_file_list_exec_source_file}, { "file-list-exec-source-files", { NULL, 0 }, mi_cmd_file_list_exec_source_files }, + { "file-list-shared-libraries", { NULL, 0 }, + mi_cmd_file_list_shared_libraries }, { "file-symbol-file", { "symbol-file", 1 }, NULL }, { "gdb-exit", { NULL, 0 }, mi_cmd_gdb_exit}, { "gdb-set", { "set", 1 }, NULL }, diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index 18b4ad7..1cb5556 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -68,6 +68,7 @@ extern mi_cmd_argv_ftype mi_cmd_exec_step; extern mi_cmd_argv_ftype mi_cmd_exec_step_instruction; extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_file; extern mi_cmd_argv_ftype mi_cmd_file_list_exec_source_files; +extern mi_cmd_argv_ftype mi_cmd_file_list_shared_libraries; extern mi_cmd_argv_ftype mi_cmd_gdb_exit; extern mi_cmd_argv_ftype mi_cmd_inferior_tty_set; extern mi_cmd_argv_ftype mi_cmd_inferior_tty_show; diff --git a/gdb/solib.c b/gdb/solib.c index 8fe35e5..975e9fb 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -1002,14 +1002,14 @@ solib_add (char *pattern, int from_tty, print them all. */ -static void +void info_sharedlibrary_command (char *pattern, int from_tty) { struct so_list *so = NULL; /* link map state variable */ int so_missing_debug_info = 0; int addr_width; - int nr_libs; - struct cleanup *table_cleanup; + int nr_libs = 0; + struct cleanup *content_cleanup; struct gdbarch *gdbarch = target_gdbarch; if (pattern) @@ -1025,42 +1025,56 @@ info_sharedlibrary_command (char *pattern, int from_tty) update_solib_list (from_tty, 0); - /* make_cleanup_ui_out_table_begin_end needs to know the number of - rows, so we need to make two passes over the libs. */ - - for (nr_libs = 0, so = so_list_head; so; so = so->next) + if (ui_out_is_mi_like_p (uiout)) + { + /* Output a simple list for MI. */ + content_cleanup = make_cleanup_ui_out_list_begin_end (uiout, + "sharedlibs"); + } + else { - if (so->so_name[0]) + /* make_cleanup_ui_out_table_begin_end needs to know the number + of rows, so we need to make two passes over the libs. */ + + for (nr_libs = 0, so = so_list_head; so; so = so->next) { - if (pattern && ! re_exec (so->so_name)) - continue; - ++nr_libs; + if (so->so_name[0]) + { + if (pattern && ! re_exec (so->so_name)) + continue; + ++nr_libs; + } } - } - table_cleanup = - make_cleanup_ui_out_table_begin_end (uiout, 4, nr_libs, - "SharedLibraryTable"); + content_cleanup = + make_cleanup_ui_out_table_begin_end (uiout, 4, nr_libs, + "SharedLibraryTable"); - /* The "- 1" is because ui_out adds one space between columns. */ - ui_out_table_header (uiout, addr_width - 1, ui_left, "from", "From"); - ui_out_table_header (uiout, addr_width - 1, ui_left, "to", "To"); - ui_out_table_header (uiout, 12 - 1, ui_left, "syms-read", "Syms Read"); - ui_out_table_header (uiout, 0, ui_noalign, - "name", "Shared Object Library"); + /* The "- 1" is because ui_out adds one space between columns. */ + ui_out_table_header (uiout, addr_width - 1, ui_left, "from", "From"); + ui_out_table_header (uiout, addr_width - 1, ui_left, "to", "To"); + ui_out_table_header (uiout, 12 - 1, ui_left, "syms-read", "Syms Read"); + ui_out_table_header (uiout, 0, ui_noalign, + "name", "Shared Object Library"); - ui_out_table_body (uiout); + ui_out_table_body (uiout); + } for (so = so_list_head; so; so = so->next) { struct cleanup *lib_cleanup; + static const char *read_names[] = { "No", "Yes (*)", "Yes" }; + int read_kind; if (! so->so_name[0]) continue; if (pattern && ! re_exec (so->so_name)) continue; - lib_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "lib"); + if (ui_out_is_mi_like_p (uiout)) + lib_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "lib"); + else + lib_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "lib"); if (so->addr_high != 0) { @@ -1073,16 +1087,28 @@ info_sharedlibrary_command (char *pattern, int from_tty) ui_out_field_skip (uiout, "to"); } - if (! ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())) + /* We check the top-level interpreter's ui-out object here for + historical compatibility: older versions of gdb did not + expose this function to MI, and so clients were forced to + parse the "info shared" output. The additional check for the + current ui-out object lets us avoid this backward + compatibility in the case of a "native" MI request. */ + if ((ui_out_is_mi_like_p (uiout) + || ! ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))) && so->symbols_loaded && !objfile_has_symbols (so->objfile)) { so_missing_debug_info = 1; + read_kind = 1; ui_out_field_string (uiout, "syms-read", "Yes (*)"); } else - ui_out_field_string (uiout, "syms-read", - so->symbols_loaded ? "Yes" : "No"); + read_kind = so->symbols_loaded ? 2 : 0; + + if (ui_out_is_mi_like_p (uiout)) + ui_out_field_int (uiout, "syms-read", read_kind); + else + ui_out_field_string (uiout, "syms-read", read_names[read_kind]); ui_out_field_string (uiout, "name", so->so_name); @@ -1091,9 +1117,13 @@ info_sharedlibrary_command (char *pattern, int from_tty) do_cleanups (lib_cleanup); } - do_cleanups (table_cleanup); + do_cleanups (content_cleanup); - if (nr_libs == 0) + if (ui_out_is_mi_like_p (uiout)) + { + /* Nothing. */ + } + else if (nr_libs == 0) { if (pattern) ui_out_message (uiout, 0, diff --git a/gdb/solib.h b/gdb/solib.h index bce21e5..c121d3a 100644 --- a/gdb/solib.h +++ b/gdb/solib.h @@ -78,4 +78,8 @@ extern void set_solib_ops (struct gdbarch *gdbarch, extern int libpthread_name_p (const char *name); +/* Print information about shared libraries. */ + +extern void info_sharedlibrary_command (char *pattern, int from_tty); + #endif /* SOLIB_H */ diff --git a/gdb/testsuite/gdb.mi/mi-solib.exp b/gdb/testsuite/gdb.mi/mi-solib.exp index ec2623e..7a94db5 100644 --- a/gdb/testsuite/gdb.mi/mi-solib.exp +++ b/gdb/testsuite/gdb.mi/mi-solib.exp @@ -50,6 +50,10 @@ if [mi_gdb_start] { mi_gdb_load ${binfile} +mi_gdb_test "200-break-insert -t main" \ + "200\\^done,bkpt=\{.*\}" \ + "set temporary breakpoint at main for solib test" + mi_run_cmd set libtest "*${libname}*" @@ -68,7 +72,7 @@ gdb_expect { -re "(${thread_selected_re})?${mi_gdb_prompt}" { } timeout { - perror "Unable to start target" + perror "timeout waiting for =library-loaded" return -1 } } @@ -78,3 +82,7 @@ if {$lib_found} { } else { fail "checking library load $libname" } + +mi_gdb_test "201-file-list-shared-libraries" \ + "201\\^done,.*name=.*$libname.*\]\]" \ + "test -file-list-shared-libraries" -- 1.7.2.3