aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2021-05-18 14:27:25 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2021-06-25 20:54:29 +0100
commitbd742128ba3b0eebda581a26c5bfa52ac0995584 (patch)
treeda0044bc2b93ad6a437c37247f79deedcfab4818 /gdb/symtab.c
parent1fb1ce02fc0e311c1dede3f2b992c9fc31124d6d (diff)
downloadgdb-bd742128ba3b0eebda581a26c5bfa52ac0995584.zip
gdb-bd742128ba3b0eebda581a26c5bfa52ac0995584.tar.gz
gdb-bd742128ba3b0eebda581a26c5bfa52ac0995584.tar.bz2
gdb: change info sources to group results by objfile
Currently the 'info sources' command lists all of the known source files together, regardless of their source, e.g. here is a session debugging a test application that makes use of a shared library: (gdb) info sources Source files for which symbols have been read in: /tmp/info-sources/test.c, /usr/include/stdc-predef.h, /tmp/info-sources/header.h, /tmp/info-sources/helper.c Source files for which symbols will be read in on demand: (gdb) In this commit I change the format of the 'info sources' results so that the results are grouped by the object file that uses that source file. Here's the same session with the new output format: (gdb) info sources /tmp/info-sources/test.x: /tmp/info-sources/test.c, /usr/include/stdc-predef.h, /tmp/info-sources/header.h /lib64/ld-linux-x86-64.so.2: (Objfile has no debug information.) system-supplied DSO at 0x7ffff7fcf000: (Objfile has no debug information.) /tmp/info-sources/libhelper.so: /tmp/info-sources/helper.c, /usr/include/stdc-predef.h, /tmp/info-sources/header.h /lib64/libc.so.6: (Objfile has no debug information.) (gdb) Notice that in the new output some source files are repeated, e.g. /tmp/info-sources/header.h, as multiple objfiles use this source file. Further, some object files are tagged with the message '(Objfile has no debug information.)', it is also possible to see the message '(Full debug information has not yet been read for this file.)', which is printed when some symtabs within an objfile have not yet been expanded. All of the existing regular expression based filtering still works. An original version of this patch added the new format as an option to 'info sources', however, it was felt that the new layout was so much better than the old style that GDB should just switch to the new result format completely. gdb/ChangeLog: * 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. gdb/doc/ChangeLog: * gdb.texinfo (Symbols): Document new output format for 'info sources'. gdb/testsuite/ChangeLog: * 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.
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c94
1 files changed, 32 insertions, 62 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index cd6da06..7fd037f 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