public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Bruno Larsen <blarsen@redhat.com>
To: gdb-patches@sourceware.org
Cc: Bruno Larsen <blarsen@redhat.com>, Eli Zaretskii <eliz@gnu.org>
Subject: [PATCH v3 2/4] gdb/cli: Improve UX when using list with no args
Date: Wed, 21 Jun 2023 12:45:43 +0200	[thread overview]
Message-ID: <20230621104545.2530552-3-blarsen@redhat.com> (raw)
In-Reply-To: <20230621104545.2530552-1-blarsen@redhat.com>

When using "list" with no arguments, GDB will first print the lines
around where the inferior is stopped, then print the next N lines until
reaching the end of file, at which point it wanrs the user "Line X out
of range, file Y only has X-1 lines.".  This is usually desireable, but
if the user can no longer see the original line, they may have forgotten
the current line or that a list command was used at all, making GDB's
error message look cryptic. It was reported in bugzilla as PR cli/30497.

This commit improves the user experince by changing the behavior of
"list" slightly when a user passes no arguments.  If the line that would
be printed is past the end of the file, GDB will now warn that the
previous list command has reached the end of file, and the current line
wil be listed again.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30497
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
---
 gdb/NEWS                        |  7 +++++++
 gdb/cli/cli-cmds.c              | 36 +++++++++++++++++++++++++++++++--
 gdb/doc/gdb.texinfo             |  7 +++++--
 gdb/source.c                    | 18 +++++++++++++++++
 gdb/source.h                    |  4 ++++
 gdb/testsuite/gdb.base/list.exp |  8 ++++----
 6 files changed, 72 insertions(+), 8 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index fd42864c692..348e73dd15f 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -77,6 +77,13 @@
   as the array would be printed by the 'print' command.  This
   functionality is also available for dprintf when dprintf-style is
   'gdb'.
+ 
+* Using the 'list' command with no arguments in a situation where the
+  command would attempt to list past the end of the file now warns the
+  user that the end of file has been reached, and prints the default
+  location.  Previously, it would error out.  The default location for
+  this purpose is the last solitary line printed, if there was one,
+  else the lines around the main function.
 
 * New commands
 
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index b0b9c08c2ec..5973aebfad3 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1244,8 +1244,40 @@ list_command (const char *arg, int from_tty)
 	  list_around_line (arg, cursal);
 	}
 
-      /* "l" or "l +" lists next ten lines.  */
-      else if (arg == NULL || arg[0] == '+')
+      /* "l" lists the next few lines, unless we're listing past the end of
+	 the file.  If it would be past the end, re-print the current line.  */
+      else if (arg == nullptr)
+	{
+	  if (can_print_line (cursal.symtab, cursal.line))
+	    print_source_lines (cursal.symtab,
+				source_lines_range (cursal.line), 0);
+	  else
+	    {
+	      warning (_("previous list command has already reached the end "
+			 "of the file. Listing default location again"));
+	      try
+		{
+		  /* Find the current line by getting the PC of the currently
+		     selected frame, and finding the line associated to it.  */
+		  frame_info_ptr frame = get_selected_frame (nullptr);
+		  CORE_ADDR curr_pc = get_frame_pc (frame);
+		  cursal = find_pc_line (curr_pc, 0);
+		}
+	      catch (const gdb_exception &e)
+		{
+		  /* If there was an exception above, it means the inferior
+		     is not running, so reset the current source location to
+		     the default.  */
+		  clear_current_source_symtab_and_line ();
+		  set_default_source_symtab_and_line ();
+		  cursal = get_current_source_symtab_and_line ();
+		}
+	      list_around_line (arg, cursal);
+	    }
+	}
+
+      /* "l +" always lists next few lines.  */
+      else if (arg[0] == '+')
 	print_source_lines (cursal.symtab,
 			    source_lines_range (cursal.line), 0);
 
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index b10c06ae91f..55010f69a1c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -9142,9 +9142,12 @@ Print lines centered around the beginning of function
 @item list
 Print more lines.  If the last lines printed were printed with a
 @code{list} command, this prints lines following the last lines
-printed; however, if the last line printed was a solitary line printed
+printed; however, if those lines are past the end of the source
+file, or if the last line printed was a solitary line printed
 as part of displaying a stack frame (@pxref{Stack, ,Examining the
-Stack}), this prints lines centered around that line.
+Stack}), this prints lines centered around that line.  If no
+@code{list} command has been used and no solitary line was printed,
+it prints the lines around the function @code{main}.
 
 @item list -
 Print lines just before the lines last printed.
diff --git a/gdb/source.c b/gdb/source.c
index 9997cccb31b..1aa08c6e080 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1484,6 +1484,24 @@ print_source_lines (struct symtab *s, source_lines_range line_range,
 			   line_range.stopline (), flags);
 }
 
+/* See source.h.  */
+
+bool
+can_print_line (struct symtab *s, int line)
+{
+  const std::vector<off_t> *offset_p;
+
+  /* If we can't get the offsets, we definitely can't print the line.  */
+  if (!g_source_cache.get_line_charpos (s, &offset_p))
+    return false;
+  if (offset_p == nullptr)
+    return false;
+
+  /* Otherwise we are able to print LINE if there are at least that many
+     lines in the symtab.  */
+  return line <= offset_p->size ();
+}
+
 
 \f
 /* Print info on range of pc's in a specified line.  */
diff --git a/gdb/source.h b/gdb/source.h
index 8fbc365680d..ae6764322d0 100644
--- a/gdb/source.h
+++ b/gdb/source.h
@@ -192,6 +192,10 @@ class source_lines_range
   int m_stopline;
 };
 
+/* Check if the line LINE can be found in the symtab S, so that it can be
+   printed.  */
+extern bool can_print_line (struct symtab *s, int line);
+
 /* Variation of previous print_source_lines that takes a range instead of a
    start and end line number.  */
 extern void print_source_lines (struct symtab *s, source_lines_range r,
diff --git a/gdb/testsuite/gdb.base/list.exp b/gdb/testsuite/gdb.base/list.exp
index 18ecd13ac0f..35e099ebaff 100644
--- a/gdb/testsuite/gdb.base/list.exp
+++ b/gdb/testsuite/gdb.base/list.exp
@@ -175,8 +175,8 @@ proc_with_prefix test_list_forward {} {
 	"list 25-34"
     gdb_test "list" "35\[ \t\]+foo \\(.*\\);.*${last_line_re}" \
 	"list 35-42"
-    gdb_test "list" "Line number 44 out of range; \[^\r\n\]+ has 43 lines\." \
-	"end of file error after \"list\" command"
+    gdb_test "list" "warning: previous list command has already reached the end of the file. Listing default location again.*1\[ \t\]+#include \"list0.h\".*" \
+	"list past end of file"
 }
 
 # Test that repeating the list linenum command doesn't print the same
@@ -194,8 +194,8 @@ proc_with_prefix test_repeat_list_command {} {
 	"list 25-34"
     gdb_test " " "35\[ \t\]+foo \\(.*\\);.*${last_line_re}" \
 	"list 35-42"
-    gdb_test "list" "Line number 44 out of range; \[^\r\n\]+ has 43 lines\." \
-	"end of file error after using 'return' to repeat the list command"
+    gdb_test "list" "warning: previous list command has already reached the end of the file. Listing default location again.*1\[ \t\]+#include \"list0.h\".*" \
+	"list past end of file"
 }
 
 proc_with_prefix test_list_backwards {} {
-- 
2.40.1


  parent reply	other threads:[~2023-06-21 10:46 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-21 10:45 [PATCH v3 0/4] Small changes to "list" command Bruno Larsen
2023-06-21 10:45 ` [PATCH v3 1/4] gdb/cli: Factor out code to list lines for the first time Bruno Larsen
2023-06-22 13:25   ` Andrew Burgess
2023-06-21 10:45 ` Bruno Larsen [this message]
2023-06-21 16:07   ` [PATCH v3 2/4] gdb/cli: Improve UX when using list with no args Keith Seitz
2023-06-22  9:54     ` Bruno Larsen
2023-06-22 13:46   ` Andrew Burgess
2023-06-27 11:35     ` Bruno Larsen
2023-06-21 10:45 ` [PATCH v3 3/4] gdb/cli: add '.' as an argument for 'list' command Bruno Larsen
2023-06-21 17:25   ` Keith Seitz
2023-06-22 10:52     ` Bruno Larsen
2023-06-22 13:51   ` Andrew Burgess
2023-06-21 10:45 ` [PATCH v3 4/4] gdb/doc: document '+' " Bruno Larsen
2023-06-21 11:13   ` Eli Zaretskii
2023-06-21 11:20     ` Bruno Larsen
2023-06-21 12:44       ` Eli Zaretskii
2023-06-21 12:55         ` Bruno Larsen
2023-06-21 14:11           ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230621104545.2530552-3-blarsen@redhat.com \
    --to=blarsen@redhat.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).