diff options
-rw-r--r-- | gdb/ChangeLog | 14 | ||||
-rw-r--r-- | gdb/NEWS | 6 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 44 | ||||
-rw-r--r-- | gdb/symtab.c | 94 | ||||
-rw-r--r-- | gdb/symtab.h | 5 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/info_sources_2-header.h | 28 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/info_sources_2-lib.c | 25 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/info_sources_2-test.c | 26 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/info_sources_2.exp | 169 |
11 files changed, 342 insertions, 81 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 637fd096a93..41f98e81287 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,19 @@ 2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com> + * NEWS: Mention changes to 'info sources'. + * symtab.c (info_sources_filter::print): Delete. + (struct output_source_filename_data) <print_header>: Delete + declaration. <printed_filename_p>: New member function. + (output_source_filename_data::print_header): Delete. + (info_sources_worker): Update group-by-objfile style output to + make it CLI suitable, simplify non-group-by-objfile now this is + only used from the MI. + (info_sources_command): Make group-by-objfile be the default for + CLI info sources command. + * symtab.h (struct info_sources_filter) <print>: Delete. + +2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com> + * NEWS: Mention additions to -file-list-exec-source-files. * mi/mi-cmd-file.c (mi_cmd_file_list_exec_source_files): Add --group-by-objfile option. @@ -221,6 +221,12 @@ ptype[/FLAGS] TYPE | EXPRESSION offsets of struct members. Default behavior is given by 'show print type hex'. +info sources + The info sources command output has been restructured. The results + are now based around a list of objfiles (executable and libraries), + and for each objfile the source files that are part of that objfile + are listed. + * Removed targets and native configurations ARM Symbian arm*-*-symbianelf* diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 20ea7f7d12d..c9f30e565e1 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,5 +1,10 @@ 2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.texinfo (Symbols): Document new output format for 'info + sources'. + +2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.texinfo (GDB/MI File Commands): Document --group-by-objfile extension for -file-list-exec-source-files. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 19b6a5f2120..f1c3e7ba847 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -19334,20 +19334,36 @@ preprocessor macros. @kindex info sources -@item info sources -Print the names of all source files in your program for which there is -debugging information, organized into two lists: files whose symbols -have already been read, and files whose symbols will be read when needed. - -@item info sources [-dirname | -basename] [--] [@var{regexp}] -Like @samp{info sources}, but only print the names of the files -matching the provided @var{regexp}. -By default, the @var{regexp} is used to match anywhere in the filename. -If @code{-dirname}, only files having a dirname matching @var{regexp} are shown. -If @code{-basename}, only files having a basename matching @var{regexp} -are shown. -The matching is case-sensitive, except on operating systems that -have case-insensitive filesystem (e.g., MS-Windows). +@item info sources @r{[}-dirname | -basename@r{]} @r{[}--@r{]} @r{[}@var{regexp}@r{]} + + +With no options @samp{info sources} prints the names of all source +files in your program for which there is debugging information. The +source files are presented based on a list of object files +(executables and libraries) currently loaded into @value{GDBN}. For +each object file all of the associated source files are listed. + +Each source file will only be printed once for each object file, but a +single source file can be repeated in the output if it is part of +multiple object files. + +If the optional @var{regexp} is provided, then only source files that +match the regular expression will be printed. The matching is +case-sensitive, except on operating systems that have case-insensitive +filesystem (e.g., MS-Windows). @samp{--} can be used before +@var{regexp} to prevent @value{GDBN} interpreting @var{regexp} as a +command option (e.g. if @var{regexp} starts with @samp{-}). + +By default, the @var{regexp} is used to match anywhere in the +filename. If @code{-dirname}, only files having a dirname matching +@var{regexp} are shown. If @code{-basename}, only files having a +basename matching @var{regexp} are shown. + +It is possible that an object file may be printed in the list with no +associated source files. This can happen when either no source files +match @var{regexp}, or, the object file was compiled without debug +information and so @value{GDBN} is unable to find any source file +names. @kindex info functions @item info functions [-q] [-n] diff --git a/gdb/symtab.c b/gdb/symtab.c index cd6da063141..7fd037f9701 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -4252,33 +4252,6 @@ info_sources_filter::matches (const char *fullname) const return true; } -/* See class declaration. */ - -void -info_sources_filter::print (struct ui_out *uiout) const -{ - if (m_c_regexp.has_value ()) - { - gdb_assert (m_regexp != nullptr); - - switch (m_match_type) - { - case match_on::DIRNAME: - uiout->message (_("(dirname matching regular expression \"%s\")"), - m_regexp); - break; - case match_on::BASENAME: - uiout->message (_("(basename matching regular expression \"%s\")"), - m_regexp); - break; - case match_on::FULLNAME: - printf_filtered (_("(filename matching regular expression \"%s\")"), - m_regexp); - break; - } - } -} - /* Data structure to maintain the state used for printing the results of the 'info sources' command. */ @@ -4312,12 +4285,6 @@ struct output_source_filename_data expanded symtab, otherwise false). */ void output (const char *disp_name, const char *fullname, bool expanded_p); - /* Prints the header messages for the source files that will be printed - with the matching info present in the current object state. - SYMBOL_MSG is a message that describes what will or has been done with - the symbols of the matching source files. */ - void print_header (const char *symbol_msg); - /* An overload suitable for use as a callback to quick_symbol_functions::map_symbol_filenames. */ void operator() (const char *filename, const char *fullname) @@ -4327,6 +4294,14 @@ struct output_source_filename_data output (filename, fullname, false); } + /* Return true if at least one filename has been printed (after a call to + output) since either this object was created, or the last call to + reset_output. */ + bool printed_filename_p () const + { + return !m_first; + } + private: /* Flag of whether we're printing the first one. */ @@ -4392,16 +4367,6 @@ output_source_filename_data::output (const char *disp_name, } } -/* See comment is class declaration above. */ - -void -output_source_filename_data::print_header (const char *symbol_msg) -{ - m_uiout->text (symbol_msg); - m_filter.print (m_uiout); - m_uiout->text ("\n"); -} - /* For the 'info sources' command, what part of the file names should we be matching the user supplied regular expression against? */ @@ -4468,13 +4433,7 @@ info_sources_worker (struct ui_out *uiout, gdb::optional<ui_out_emit_tuple> output_tuple; gdb::optional<ui_out_emit_list> sources_list; - gdb_assert (!group_by_objfile || uiout->is_mi_like_p ()); - - if (!group_by_objfile) - { - if (!uiout->is_mi_like_p ()) - data.print_header (_("Source files for which symbols have been read in:\n")); - } + gdb_assert (group_by_objfile || uiout->is_mi_like_p ()); for (objfile *objfile : current_program_space->objfiles ()) { @@ -4482,18 +4441,31 @@ info_sources_worker (struct ui_out *uiout, { output_tuple.emplace (uiout, nullptr); uiout->field_string ("filename", objfile_name (objfile)); + uiout->text (":\n"); bool debug_fully_readin = !objfile->has_unexpanded_symtabs (); - const char *debug_info_state; - if (objfile_has_symbols (objfile)) + if (uiout->is_mi_like_p ()) { - if (debug_fully_readin) - debug_info_state = "fully-read"; + const char *debug_info_state; + if (objfile_has_symbols (objfile)) + { + if (debug_fully_readin) + debug_info_state = "fully-read"; + else + debug_info_state = "partially-read"; + } else - debug_info_state = "partially-read"; + debug_info_state = "none"; + current_uiout->field_string ("debug-info", debug_info_state); } else - debug_info_state = "none"; - current_uiout->field_string ("debug-info", debug_info_state); + { + if (!debug_fully_readin) + uiout->text ("(Full debug information has not yet been read " + "for this file.)\n"); + if (!objfile_has_symbols (objfile)) + uiout->text ("(Objfile has no debug information.)\n"); + uiout->text ("\n"); + } sources_list.emplace (uiout, "sources"); } @@ -4510,6 +4482,8 @@ info_sources_worker (struct ui_out *uiout, if (group_by_objfile) { objfile->map_symbol_filenames (data, true /* need_fullname */); + if (data.printed_filename_p ()) + uiout->text ("\n\n"); data.reset_output (); sources_list.reset (); output_tuple.reset (); @@ -4518,12 +4492,8 @@ info_sources_worker (struct ui_out *uiout, if (!group_by_objfile) { - uiout->text ("\n\n"); - if (!uiout->is_mi_like_p ()) - data.print_header (_("Source files for which symbols will be read in on demand:\n")); data.reset_output (); map_symbol_filenames (data, true /*need_fullname*/); - uiout->text ("\n"); } } @@ -4559,7 +4529,7 @@ info_sources_command (const char *args, int from_tty) match_type = info_sources_filter::match_on::FULLNAME; info_sources_filter filter (match_type, regex); - info_sources_worker (current_uiout, false, filter); + info_sources_worker (current_uiout, true, filter); } /* Compare FILE against all the entries of FILENAMES. If BASENAMES is diff --git a/gdb/symtab.h b/gdb/symtab.h index 968b4476993..471ae9ef448 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -2420,11 +2420,6 @@ struct info_sources_filter then this function will always return true. */ bool matches (const char *fullname) const; - /* Print a single line describing this filter to UIOUT, used as part of - the "info sources" command output. If there is no filter in place - then nothing is printed. */ - void print (struct ui_out *uiout) const; - private: /* The type of filtering in place. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 8a8c7f22ea3..26dcea62511 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.base/info_sources_2-header.h: New file. + * gdb.base/info_sources_2-lib.c: New file. + * gdb.base/info_sources_2-test.c: New file. + * gdb.base/info_sources_2.exp: New file. + +2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com> + * gdb.mi/mi-info-sources.exp: Add additional tests. 2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com> diff --git a/gdb/testsuite/gdb.base/info_sources_2-header.h b/gdb/testsuite/gdb.base/info_sources_2-header.h new file mode 100644 index 00000000000..b3379babc0a --- /dev/null +++ b/gdb/testsuite/gdb.base/info_sources_2-header.h @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2021 Free Software Foundation, Inc. + + 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 INFO_SOURCES_2_HEADER +#define INFO_SOURCES_2_HEADER + +extern int foo (void); + +inline static int compare_values (int a, int b) +{ + return a == b; +} + +#endif /* INFO_SOURCES_2_HEADER */ diff --git a/gdb/testsuite/gdb.base/info_sources_2-lib.c b/gdb/testsuite/gdb.base/info_sources_2-lib.c new file mode 100644 index 00000000000..7df1a8114ad --- /dev/null +++ b/gdb/testsuite/gdb.base/info_sources_2-lib.c @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2021 Free Software Foundation, Inc. + + 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/>. */ + + +#include "info_sources_2-header.h" + +int +foo () +{ + return compare_values (0, 1); +} diff --git a/gdb/testsuite/gdb.base/info_sources_2-test.c b/gdb/testsuite/gdb.base/info_sources_2-test.c new file mode 100644 index 00000000000..87a030ae87d --- /dev/null +++ b/gdb/testsuite/gdb.base/info_sources_2-test.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2021 Free Software Foundation, Inc. + + 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/>. */ + + +#include "info_sources_2-header.h" + +int +main () +{ + int res = foo (); + return compare_values (res, 1); +} diff --git a/gdb/testsuite/gdb.base/info_sources_2.exp b/gdb/testsuite/gdb.base/info_sources_2.exp new file mode 100644 index 00000000000..3aed25b07ac --- /dev/null +++ b/gdb/testsuite/gdb.base/info_sources_2.exp @@ -0,0 +1,169 @@ +# Copyright 2021 Free Software Foundation, Inc. + +# 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/>. + +# Test 'info sources' when the test file makes use of a shared +# library. + +if { [skip_shlib_tests] } { + return 0 +} + +standard_testfile -test.c -lib.c +set solib_name [standard_output_file ${testfile}-lib.so] + +if { [gdb_compile_shlib ${srcdir}/${subdir}/${srcfile2} ${solib_name} \ + {debug}] != "" } { + untested "failed to compile shared library" + return -1 +} + +if {[gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile} executable \ + [list debug shlib=${solib_name} ]] != ""} { + untested "failed to compile executable" + return -1 +} + +clean_restart ${binfile} + +if ![runto foo] { + untested "failed to run to function foo" + return -1 +} + +# Invoke 'info sources EXTRA_ARGS' and extract the results. +# The results are then compared to the list ARGS. +# +# The list ARGS should consist of pairs of values, the first item being the +# path to an object file, and the second item being the name of a source file. +# This proc checks that source file was listed as being a source file for the +# given object file. +# +# If the name of the source file starts with the character "!" (exclamation +# character, without the quotes) then the check is inverted, that the source +# file is NOT listed for the given object file. +proc run_info_sources { extra_args args } { + global gdb_prompt srcdir subdir + + with_test_prefix "args: ${extra_args}" { + + # The results of running info sources will be placed into this local. + array set info_sources {} + + # The command we are going to run. + set cmd "info sources ${extra_args}" + set command_regex [string_to_regexp $cmd] + + # Run the command and extract the results into INFO_SOURCES. + set objfile_name "" + set source_files {} + gdb_test_multiple $cmd "" { + -re "${command_regex}\r\n" { + exp_continue + } + + -re "^(\[^\r\n\]+):\r\n" { + set objfile_name $expect_out(1,string) + exp_continue + } + + -re "^\\(Full debug information has not yet been read for this file\\.\\)\r\n" { + exp_continue + } + + -re "^\r\n" { + exp_continue + } + + -re "^$gdb_prompt $" { + pass $gdb_test_name + } + + -re "^(\[^\r\n\]+)\r\n" { + if { $objfile_name == "" } { + fail "${gdb_test_name} (no objfile name)" + return + } + + set files {} + foreach f [split $expect_out(1,string) ,] { + lappend files [string trim $f] + } + set info_sources($objfile_name) $files + set $objfile_name "" + exp_continue + } + } + + # Now check ARGS agaisnt the values held in INFO_SOURCES map. + foreach {objfile sourcefile} $args { + # First, figure out if we're expecting SOURCEFILE to be present, + # or not. + set present True + set match_type "is" + if {[string index $sourcefile 0] == "!"} { + set present False + set match_type "is not" + set sourcefile [string range $sourcefile 1 end] + } + + # Figure out the path for SOURCEFILE that we're looking for. + set sourcepath [file normalize ${srcdir}/${subdir}/${sourcefile}] + + # Make sure we handle the case where there are no source files + # associated with a particular objfile. + set source_list {} + if [info exists info_sources($objfile)] { + set source_list $info_sources($objfile) + } + + # Now perform the search, and check the results. + set idx [lsearch -exact $source_list $sourcepath] + gdb_assert {($present && $idx >= 0) || (!$present && $idx == -1)} \ + "source file '$sourcefile' ${match_type} present for '[file tail $objfile]'" + } + } +} + +# The actual tests. + +run_info_sources "" \ + ${binfile} ${srcfile} \ + ${binfile} ${testfile}-header.h \ + ${solib_name} ${srcfile2} \ + ${solib_name} ${testfile}-header.h + +run_info_sources "-basename info_sources_2" \ + ${binfile} ${srcfile} \ + ${binfile} ${testfile}-header.h \ + ${solib_name} ${srcfile2} \ + ${solib_name} ${testfile}-header.h + +run_info_sources "-basename \\.c" \ + ${binfile} ${srcfile} \ + ${binfile} !${testfile}-header.h \ + ${solib_name} ${srcfile2} \ + ${solib_name} !${testfile}-header.h + +run_info_sources "-basename -- -test\\.c" \ + ${binfile} ${srcfile} \ + ${binfile} !${testfile}-header.h \ + ${solib_name} !${srcfile2} \ + ${solib_name} !${testfile}-header.h + +run_info_sources "-basename -- -lib\\.c" \ + ${binfile} !${srcfile} \ + ${binfile} !${testfile}-header.h \ + ${solib_name} ${srcfile2} \ + ${solib_name} !${testfile}-header.h |