gdb: New maint info line-table command.

Message ID ca54477642135f97eda104b54da83ae21f483914.1454796848.git.andrew.burgess@embecosm.com
State New, archived
Headers

Commit Message

Andrew Burgess Feb. 6, 2016, 10:16 p.m. UTC
  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.
	(_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                    |  6 +++
 gdb/NEWS                         |  3 ++
 gdb/doc/ChangeLog                |  5 +++
 gdb/doc/gdb.texinfo              |  9 +++++
 gdb/symmisc.c                    | 84 ++++++++++++++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog          |  4 ++
 gdb/testsuite/gdb.base/maint.exp | 16 ++++++++
 7 files changed, 127 insertions(+)
  

Comments

Eli Zaretskii Feb. 7, 2016, 4:15 p.m. UTC | #1
> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Cc: Andrew Burgess <andrew.burgess@embecosm.com>
> Date: Sat,  6 Feb 2016 22:16:23 +0000
> 
> 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.

Thanks.

> +@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 @var{filename}
> +
> +List the @code{struct linetable} for the symtab with @var{filename}.

I'd suggest to tell here in a couple of words what that structure
includes.

> +If @var{filename} is not given then the the @code{struct linetable}
                                       ^^^^^^^
"the" twice

> +that contains the current @var{pc} is given.
                                      ^^^^^^^^
"is listed"

> +  add_cmd ("line-table", class_maintenance, maintenance_info_line_tables, _("\
> +List line tables contents for specified symtab.\n\

I suggest "List contents of line tables for the specified symtab."

The documentation parts are okay with these fixed.
  
Pedro Alves Feb. 17, 2016, 11:19 a.m. UTC | #2
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.)

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a2b0d39..03366d3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@ 
+2016-02-06  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* symmisc.c (maintenance_info_line_tables): New function.
+	(_initialize_symmisc): Register 'maint info line-table' command.
+	* NEWS: Mention new command.
+
 2016-02-04  Yao Qi  <yao.qi@linaro.org>
 
 	* remote.c (remote_wait_as): Set rs->waiting_for_stop_reply to
diff --git a/gdb/NEWS b/gdb/NEWS
index 962eae4..b868791 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -98,6 +98,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 05d2694..64465ba 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-01  Doug Evans  <dje@google.com>
 
 	* gdb.texinfo (Value Sizes): Fix typo.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 2d09d13..c6aa683 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -17066,6 +17066,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 @var{filename}
+
+List the @code{struct linetable} for the symtab with @var{filename}.
+If @var{filename} is not given then the the @code{struct linetable}
+that contains the current @var{pc} is given.
+
 @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..eac7925 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -949,6 +949,84 @@  block_depth (struct block *block)
 }
 
 
+/* 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);
+  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));
+
+  ui_out_text (uiout, "Line table for `");
+  ui_out_text (uiout, symtab_to_filename_for_display (symtab));
+  ui_out_text (uiout, "':\n");
+
+  table_cleanup
+    = make_cleanup_ui_out_table_begin_end (uiout, 3,
+					   linetable->nitems,
+					   "line-table");
+
+  /* Leave space for 6 digits of index and line number.  After that the
+     tables will just not format as well.  */
+  ui_out_table_header (uiout, 6, ui_left, "index", "INDEX");
+  ui_out_table_header (uiout, 6, ui_right, "line", "LINE");
+  ui_out_table_header (uiout, (sizeof (CORE_ADDR) * 2 + 2)
+		       , ui_left, "address", "ADDRESS");
+  ui_out_table_body (uiout);
+
+  for (i = 0; i < linetable->nitems; ++i)
+    {
+      struct linetable_entry *item;
+      struct cleanup *row_cleanup;
+
+      item = &linetable->item [i];
+
+      row_cleanup
+	= make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+
+      ui_out_field_int (uiout, "index", i);
+      ui_out_field_int (uiout, "line", item->line);
+      ui_out_field_string (uiout, "address", core_addr_to_string (item->pc));
+
+      ui_out_text (uiout, "\n");
+      do_cleanups (row_cleanup);
+    }
+
+  do_cleanups (table_cleanup);
+}
+
+
 /* Do early runtime initializations.  */
 
 void
@@ -982,6 +1060,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 046f112..e2015a8 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-04  Yao Qi  <yao.qi@linaro.org>
 
 	* gdb.base/foll-exec-mode.c: Include limits.h.
diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp
index 79924a7..93236ce 100644
--- a/gdb/testsuite/gdb.base/maint.exp
+++ b/gdb/testsuite/gdb.base/maint.exp
@@ -471,6 +471,22 @@  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" \
+    "Line table for `\[^\n\r\]+${srcfile}':.*INDEX.*LINE.*ADDRESS.*" \
+    "maint info line-table w/o a file name"
+
+gdb_test "maint info line-table ${srcfile}" \
+    "Line table for `\[^\n\r\]+${srcfile}':.*INDEX.*LINE.*ADDRESS.*" \
+    "maint info line-table with filename of current symtab"
+
+gdb_test "maint info line-table ${srcfile2}" \
+    "Line table for `\[^\n\r\]+${srcfile2}':.*INDEX.*LINE.*ADDRESS.*" \
+    "maint info line-table with filename of symtab that is not current"
+
+gdb_test "maint info line-table xxx.c" \
+    "No matching symbol table found for `.*'." \
+    "maint info line-table with invalid filename"
+
 set timeout $oldtimeout
 
 #============test help on maint commands