[v4,3/4] gdb/cli: Improve UX when using list with no args
Commit Message
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. It now prints that the
end of the file has been reached and recommends that the user use the
command "list ." instead.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30497
---
gdb/NEWS | 5 +++++
gdb/cli/cli-cmds.c | 17 +++++++++++++----
gdb/doc/gdb.texinfo | 4 +++-
gdb/source.c | 16 ++++++++++++++++
gdb/source.h | 7 +++++++
gdb/testsuite/gdb.base/list.exp | 8 ++++----
6 files changed, 48 insertions(+), 9 deletions(-)
Comments
> Cc: Bruno Larsen <blarsen@redhat.com>
> Date: Thu, 13 Jul 2023 12:24:10 +0200
> From: Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org>
>
> 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. It now prints that the
> end of the file has been reached and recommends that the user use the
> command "list ." instead.
>
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30497
> ---
> gdb/NEWS | 5 +++++
> gdb/cli/cli-cmds.c | 17 +++++++++++++----
> gdb/doc/gdb.texinfo | 4 +++-
> gdb/source.c | 16 ++++++++++++++++
> gdb/source.h | 7 +++++++
> gdb/testsuite/gdb.base/list.exp | 8 ++++----
> 6 files changed, 48 insertions(+), 9 deletions(-)
Thanks, the documentation parts are okay.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Just wanted to point out some trivial typos:
On 7/13/23 03:24, Bruno Larsen via Gdb-patches wrote:
> 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
^^^^^ "warns"
> of range, file Y only has X-1 lines.". This is usually desireable, but
"desirable" ^^^^^^^^^^
> 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
^^^^^^^^^ "experience"
> "list" slightly when a user passes no arguments. It now prints that the
> end of the file has been reached and recommends that the user use the
> command "list ." instead.
Apologies for the nitpicking after the patch has been approved.
Keith
@@ -88,6 +88,11 @@
print the location where the inferior is stopped. If the inferior hasn't
started yet, the command will print around the main function.
+* 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, refers the user to the
+ newly added '.' argument
+
* New commands
maintenance print record-instruction [ N ]
@@ -1246,10 +1246,19 @@ 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] == '+')
- print_source_lines (cursal.symtab,
- source_lines_range (cursal.line), 0);
+ /* "l" and "l +" lists the next few lines, unless we're listing past
+ the end of the file. */
+ else if (arg == nullptr || arg[0] == '+')
+ {
+ if (last_symtab_line (cursal.symtab) >= cursal.line)
+ print_source_lines (cursal.symtab,
+ source_lines_range (cursal.line), 0);
+ else
+ {
+ error (_("End of the file was already reached, use \"list .\" to"
+ " list the current location again"));
+ }
+ }
/* "l -" lists previous ten lines, the ones before the ten just
listed. */
@@ -9144,7 +9144,9 @@ 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
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.
@@ -1484,6 +1484,22 @@ print_source_lines (struct symtab *s, source_lines_range line_range,
line_range.stopline (), flags);
}
+/* See source.h. */
+
+int
+last_symtab_line (struct symtab *s)
+{
+ const std::vector<off_t> *offsets;
+
+ /* Try to get the offsets for the start of each line. */
+ if (!g_source_cache.get_line_charpos (s, &offsets))
+ return false;
+ if (offsets == nullptr)
+ return false;
+
+ return offsets->size ();
+}
+
/* Print info on range of pc's in a specified line. */
@@ -192,6 +192,13 @@ class source_lines_range
int m_stopline;
};
+/* Get the number of the last line in the given symtab. */
+extern int last_symtab_line (struct symtab *s);
+
+/* 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,
@@ -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" "End of the file was already reached, use \"list .\" to list the current location again" \
+ "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" "End of the file was already reached, use \"list .\" to list the current location again" \
+ "list past end of file"
}
proc_with_prefix test_list_backwards {} {