gdb: New maint info line-table command.
Commit Message
* Pedro Alves <palves@redhat.com> [2016-02-17 11:19:06 +0000]:
> Given this is a maint command, I'm fine with it as is.
>
> I have a few suggestions below though.
>
> On 02/06/2016 10:16 PM, Andrew Burgess wrote:
>
> > +/* Implement the 'maint info line-table' command. */
> > +
> > +static void
> > +maintenance_info_line_tables (char *arg, int from_tty)
> > +{
> > + struct ui_out *uiout = current_uiout;
> > + struct symtab *symtab = NULL;
> > + struct linetable *linetable;
> > + struct cleanup *table_cleanup;
> > + int i;
> > +
> > + if (arg != NULL)
> > + symtab = lookup_symtab (arg);
>
> Given there may be multiple symtabs with the same file name, I'd think it
> better if this printed information on all symtabs that matched.
>
> Basically, move the line table printing to a helper function, and then
> use iterate_over_symtabs instead of lookup_symtab.
>
> > + else
> > + {
> > + struct frame_info *frame;
> > + CORE_ADDR pc;
> > +
> > + frame = get_selected_frame (_("No frame selected."));
> > + pc = get_frame_address_in_block (frame);
> > + symtab = find_pc_line_symtab (pc);
> > + }
> > +
> > + if (symtab == NULL)
> > + {
> > + if (arg)
> > + error (_("No matching symbol table found for `%s'."), arg);
> > + else
> > + error (_("No matching symbol table found."));
> > + }
> > +
> > + linetable = SYMTAB_LINETABLE (symtab);
> > + if (linetable == NULL)
> > + error (_("Symbol table for `%s' has no line table."),
> > + symtab_to_filename_for_display (symtab));
> > + if (linetable->nitems <= 0)
> > + error (_("Line table for symbol table `%s' has no lines"),
> > + symtab_to_filename_for_display (symtab));
>
> Seems odd for these to be errors. Consider a gdb script or user-command
> that does:
>
> maint info line-table
> maint info symtabs
>
> If there's no line table, should the whole script error out, or just
> print that as info? I think the latter.
>
> > +
> > + ui_out_text (uiout, "Line table for `");
> > + ui_out_text (uiout, symtab_to_filename_for_display (symtab));
> > + ui_out_text (uiout, "':\n");
>
> (It'd probably be useful to also show the full name, to be sure you're
> looking at the symtab you think you're looking at.)
I've reworked the patch to, I hope, follow your suggestions.
I now follow the same pattern as for 'maint info symtabs', so I take a
regexp, and list line tables for symtabs matching the regexp, or all
symtabs if not regexp is given.
This does mean, that like 'maint info symtabs' you need to use 'maint
expand-symtabs' if you want to see all line tables, but that seems
acceptable.
I've dropped the use of ui_out_* style functions in favour of just
printf_filtered, this is inline with the other maintenance function.
I don't know if that's OK, or if you'd rather that maintenance
commands switch to the more structured output.
The only downside to this change that I miss is the feature of being
able to quickly display the information for the current symtab; this
is probably how I use this sort of information the most, gdb does
something strange and I want to figure out what the internal state is
for where I am in the program right now. I might add some short-cut
mechanism (a special regexp pattern maybe) that does this.... but if I
do, that will come later.
How's this version?
Thanks,
Andrew
---
Add a new command 'maint info line-table' to display the contents of
GDB's internal line table structure. Useful when trying to understand
problems (within gdb) relating to line tables.
gdb/ChangeLog:
* symmisc.c (maintenance_info_line_tables): New function.
(maintenance_print_one_line_table): New function.
(_initialize_symmisc): Register 'maint info line-table' command.
* NEWS: Mention new command.
gdb/doc/ChangeLog:
* gdb.texinfo (Symbols): Document new 'maint info line-table'
command.
gdb/testsuite/ChangeLog:
* gdb.base/maint.exp: New tests for 'maint info line-table'.
---
gdb/ChangeLog | 7 ++++
gdb/NEWS | 3 ++
gdb/doc/ChangeLog | 5 +++
gdb/doc/gdb.texinfo | 9 ++++
gdb/symmisc.c | 90 ++++++++++++++++++++++++++++++++++++++++
gdb/testsuite/ChangeLog | 4 ++
gdb/testsuite/gdb.base/maint.exp | 20 +++++++++
7 files changed, 138 insertions(+)
Comments
On 02/21/2016 12:06 AM, Andrew Burgess wrote:
> + if (linetable == NULL)
> + printf_filtered (_("No line table.\n"));
> + else if (linetable->nitems <= 0)
> + printf_filtered (_("Line table has no lines.\n"));
> + else
> + {
> + int i;
> +
> + /* Leave space for 6 digits of index and line number. After that the
> + tables will just not format as well. */
> + printf_filtered ("%-6s %6s %s\n",
Wrap these in an extra (), otherwise I think the ARI will complain.
> + _("INDEX"), _("LINE"), _("ADDRESS"));
> +
> + for (i = 0; i < linetable->nitems; ++i)
> + {
> + struct linetable_entry *item;
> + struct cleanup *row_cleanup;
> +
> + item = &linetable->item [i];
> + printf_filtered ("%-6d %6d %s\n", i, item->line,
Ditto.
> + core_addr_to_string (item->pc));
> + }
> + }
> +
> + return 0;
> +}
> +
> +/* Implement the 'maint info line-table' command. */
> +
> +static void
> +maintenance_info_line_tables (char *regexp, int from_tty)
> +{
> + struct program_space *pspace;
> + struct objfile *objfile;
> +
> + dont_repeat ();
> +
> + if (regexp)
regexp != NULL.
> + re_comp (regexp);
> +
> + ALL_PSPACES (pspace)
> + ALL_PSPACE_OBJFILES (pspace, objfile)
> + {
> + struct compunit_symtab *cust;
> + struct symtab *symtab;
> +
> + ALL_OBJFILE_COMPUNITS (objfile, cust)
> + {
> + ALL_COMPUNIT_FILETABS (cust, symtab)
> + {
> + QUIT;
> +
> + if (! regexp
regexp == NULL.
> void
> @@ -982,6 +1066,12 @@ linetables --- just the symbol table structures themselves.\n\
> With an argument REGEXP, list the symbol tables with matching names."),
> &maintenanceinfolist);
>
> + add_cmd ("line-table", class_maintenance, maintenance_info_line_tables, _("\
> +List line tables contents for specified symtab.\n\
> +Given the filename of a symtab, list the contents of the\n\
> +associated line table."),
Shouldn't the last sentence be updated to mention REGEXP, like the
maint info symtabs entry above?
> +maint info line-table FILENAME
> + Display the contents of GDB's internal line table data struture.
Ditto.
> +List the @code{struct linetable} from each @code{struct symtab} whose
> +name matches @var{regexp}. If @var{regexp} is not given, list the
> +@code{struct linetable} from all @code{struct symtab}.
Either "from all @code{struct symtab} instances", or "from all symtabs",
I think.
Otherwise LGTM. Thanks for doing this.
* Pedro Alves <palves@redhat.com> [2016-03-01 19:57:45 +0000]:
> On 02/21/2016 12:06 AM, Andrew Burgess wrote:
>
>
> >+ if (linetable == NULL)
> >+ printf_filtered (_("No line table.\n"));
> >+ else if (linetable->nitems <= 0)
> >+ printf_filtered (_("Line table has no lines.\n"));
> >+ else
> >+ {
> >+ int i;
> >+
> >+ /* Leave space for 6 digits of index and line number. After that the
> >+ tables will just not format as well. */
> >+ printf_filtered ("%-6s %6s %s\n",
>
> Wrap these in an extra (), otherwise I think the ARI will complain.
>
>
> >+ _("INDEX"), _("LINE"), _("ADDRESS"));
> >+
> >+ for (i = 0; i < linetable->nitems; ++i)
> >+ {
> >+ struct linetable_entry *item;
> >+ struct cleanup *row_cleanup;
> >+
> >+ item = &linetable->item [i];
> >+ printf_filtered ("%-6d %6d %s\n", i, item->line,
>
> Ditto.
>
> >+ core_addr_to_string (item->pc));
> >+ }
> >+ }
> >+
> >+ return 0;
> >+}
> >+
> >+/* Implement the 'maint info line-table' command. */
> >+
> >+static void
> >+maintenance_info_line_tables (char *regexp, int from_tty)
> >+{
> >+ struct program_space *pspace;
> >+ struct objfile *objfile;
> >+
> >+ dont_repeat ();
> >+
> >+ if (regexp)
>
> regexp != NULL.
>
> >+ re_comp (regexp);
> >+
> >+ ALL_PSPACES (pspace)
> >+ ALL_PSPACE_OBJFILES (pspace, objfile)
> >+ {
> >+ struct compunit_symtab *cust;
> >+ struct symtab *symtab;
> >+
> >+ ALL_OBJFILE_COMPUNITS (objfile, cust)
> >+ {
> >+ ALL_COMPUNIT_FILETABS (cust, symtab)
> >+ {
> >+ QUIT;
> >+
> >+ if (! regexp
>
> regexp == NULL.
>
> > void
> >@@ -982,6 +1066,12 @@ linetables --- just the symbol table structures themselves.\n\
> > With an argument REGEXP, list the symbol tables with matching names."),
> > &maintenanceinfolist);
> >
> >+ add_cmd ("line-table", class_maintenance, maintenance_info_line_tables, _("\
> >+List line tables contents for specified symtab.\n\
> >+Given the filename of a symtab, list the contents of the\n\
> >+associated line table."),
>
> Shouldn't the last sentence be updated to mention REGEXP, like the
> maint info symtabs entry above?
>
> > +maint info line-table FILENAME
> > + Display the contents of GDB's internal line table data struture.
>
> Ditto.
>
> > +List the @code{struct linetable} from each @code{struct symtab} whose
> > +name matches @var{regexp}. If @var{regexp} is not given, list the
> > +@code{struct linetable} from all @code{struct symtab}.
>
> Either "from all @code{struct symtab} instances", or "from all symtabs", I
> think.
>
> Otherwise LGTM. Thanks for doing this.
Thanks for the review. Sorry for the delay in moving this on. I've
pushed this patch with the fixes that you pointed out above.
Thanks again,
Andrew
@@ -1,3 +1,10 @@
+2016-02-06 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * symmisc.c (maintenance_info_line_tables): New function.
+ (maintenance_print_one_line_table): New function.
+ (_initialize_symmisc): Register 'maint info line-table' command.
+ * NEWS: Mention new command.
+
2016-02-18 Marcin Kościelnicki <koriakin@0x04.net>
* s390-linux-tdep.c (s390_guess_tracepoint_registers): New function.
@@ -114,6 +114,9 @@ maint set bfd-sharing
maint show bfd-sharing
Control the reuse of bfd objects.
+maint info line-table FILENAME
+ Display the contents of GDB's internal line table data struture.
+
set debug bfd-cache
show debug bfd-cache
Control display of debugging info regarding bfd caching.
@@ -1,3 +1,8 @@
+2016-02-06 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * gdb.texinfo (Symbols): Document new 'maint info line-table'
+ command.
+
2016-02-18 Walfred Tedeschi <walfred.tedeschi@intel.com>
* gdb.texinfo (Signals): Add bound violation display hints for
@@ -17093,6 +17093,15 @@ line 1574.
(@value{GDBP})
@end smallexample
+@kindex maint info line-table
+@cindex listing @value{GDBN}'s internal line tables
+@cindex line tables, listing @value{GDBN}'s internal
+@item maint info line-table @r{[} @var{regexp} @r{]}
+
+List the @code{struct linetable} from each @code{struct symtab} whose
+name matches @var{regexp}. If @var{regexp} is not given, list the
+@code{struct linetable} from all @code{struct symtab}.
+
@kindex maint set symbol-cache-size
@cindex symbol cache size
@item maint set symbol-cache-size @var{size}
@@ -949,6 +949,90 @@ block_depth (struct block *block)
}
+/* Used by MAINTENANCE_INFO_LINE_TABLES to print the information about a
+ single line table. */
+
+static int
+maintenance_print_one_line_table (struct symtab *symtab, void *data)
+{
+ struct linetable *linetable;
+ struct objfile *objfile;
+
+ objfile = symtab->compunit_symtab->objfile;
+ printf_filtered (_("objfile: %s ((struct objfile *) %s)\n"),
+ objfile_name (objfile),
+ host_address_to_string (objfile));
+ printf_filtered (_("compunit_symtab: ((struct compunit_symtab *) %s)\n"),
+ host_address_to_string (symtab->compunit_symtab));
+ printf_filtered (_("symtab: %s ((struct symtab *) %s)\n"),
+ symtab_to_fullname (symtab),
+ host_address_to_string (symtab));
+ linetable = SYMTAB_LINETABLE (symtab);
+ printf_filtered (_("linetable: ((struct linetable *) %s):\n"),
+ host_address_to_string (linetable));
+
+ if (linetable == NULL)
+ printf_filtered (_("No line table.\n"));
+ else if (linetable->nitems <= 0)
+ printf_filtered (_("Line table has no lines.\n"));
+ else
+ {
+ int i;
+
+ /* Leave space for 6 digits of index and line number. After that the
+ tables will just not format as well. */
+ printf_filtered ("%-6s %6s %s\n",
+ _("INDEX"), _("LINE"), _("ADDRESS"));
+
+ for (i = 0; i < linetable->nitems; ++i)
+ {
+ struct linetable_entry *item;
+ struct cleanup *row_cleanup;
+
+ item = &linetable->item [i];
+ printf_filtered ("%-6d %6d %s\n", i, item->line,
+ core_addr_to_string (item->pc));
+ }
+ }
+
+ return 0;
+}
+
+/* Implement the 'maint info line-table' command. */
+
+static void
+maintenance_info_line_tables (char *regexp, int from_tty)
+{
+ struct program_space *pspace;
+ struct objfile *objfile;
+
+ dont_repeat ();
+
+ if (regexp)
+ re_comp (regexp);
+
+ ALL_PSPACES (pspace)
+ ALL_PSPACE_OBJFILES (pspace, objfile)
+ {
+ struct compunit_symtab *cust;
+ struct symtab *symtab;
+
+ ALL_OBJFILE_COMPUNITS (objfile, cust)
+ {
+ ALL_COMPUNIT_FILETABS (cust, symtab)
+ {
+ QUIT;
+
+ if (! regexp
+ || re_exec (symtab_to_filename_for_display (symtab)))
+ maintenance_print_one_line_table (symtab, NULL);
+ }
+ }
+ }
+}
+
+
+
/* Do early runtime initializations. */
void
@@ -982,6 +1066,12 @@ linetables --- just the symbol table structures themselves.\n\
With an argument REGEXP, list the symbol tables with matching names."),
&maintenanceinfolist);
+ add_cmd ("line-table", class_maintenance, maintenance_info_line_tables, _("\
+List line tables contents for specified symtab.\n\
+Given the filename of a symtab, list the contents of the\n\
+associated line table."),
+ &maintenanceinfolist);
+
add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs,
_("\
Check consistency of currently expanded symtabs."),
@@ -1,3 +1,7 @@
+2016-02-06 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * gdb.base/maint.exp: New tests for 'maint info line-table'.
+
2016-02-18 Iain Buclaw <ibuclaw@gdcproject.org>
* lib/future.exp: Add D support.
@@ -471,6 +471,26 @@ gdb_test "maint" \
"\"maintenance\" must be followed by the name of a maintenance command\\.\r\nList.*unambiguous\\..*" \
"maint w/o args"
+gdb_test "maint info line-table" \
+ "symtab: \[^\n\r\]+${srcfile}.*\\(\\(struct symtab \\*\\) $hex\\)\r\nlinetable: \\(\\(struct linetable \\*\\) $hex\\):\r\nINDEX.*LINE.*ADDRESS.*" \
+ "maint info line-table w/o a file name"
+
+gdb_test "maint info line-table ${srcfile}" \
+ "symtab: \[^\n\r\]+${srcfile}.*INDEX.*LINE.*ADDRESS.*" \
+ "maint info line-table with filename of current symtab"
+
+gdb_test_no_output "maint info line-table ${srcfile2}" \
+ "maint info line-table with filename of symtab that is not currently expanded"
+
+gdb_test_no_output "maint expand-symtabs"
+
+gdb_test "maint info line-table ${srcfile2}" \
+ "symtab: \[^\n\r\]+${srcfile2}.*INDEX.*LINE.*ADDRESS.*" \
+ "maint info line-table with filename of symtab that is not current"
+
+gdb_test_no_output "maint info line-table xxx.c" \
+ "maint info line-table with invalid filename"
+
set timeout $oldtimeout
#============test help on maint commands