diff mbox

gdb: New maint info line-table command.

Message ID 20160221000652.GA15799@embecosm.com
State New
Headers show

Commit Message

Andrew Burgess Feb. 21, 2016, 12:06 a.m. UTC
* 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

Pedro Alves March 1, 2016, 7:57 p.m. UTC | #1
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.
Andrew Burgess March 11, 2016, 10:54 p.m. UTC | #2
* 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
diff mbox

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 274d98b..9e7f6d5 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/NEWS b/gdb/NEWS
index 64c4869..22cd771 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -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.
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 189dfdc..5b33e75 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -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
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 5db7cf2..e36f73b 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -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}
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 69b7e8e..255c799 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -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."),
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 5676cac..77cce58 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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.
diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp
index 79924a7..f926c8b 100644
--- a/gdb/testsuite/gdb.base/maint.exp
+++ b/gdb/testsuite/gdb.base/maint.exp
@@ -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