[PATCH v3] gdb: Change "list ." command's error when no debuginfo is available
Andrew Burgess
aburgess@redhat.com
Thu May 2 07:54:55 GMT 2024
Guinevere Larsen <blarsen@redhat.com> writes:
> From: Simon Marchi <simark@simark.ca>
>
> Currently, when a user tries to list the current location, there are 2
> different error messages that can happen, either:
>
> (gdb) list .
> No symbol table is loaded. Use the "file" command.
> or
> (gdb) list .
> No debug information available to print source lines.
>
> The difference here is if gdb can find any symtabs at all or not, which
> is not something too important for end-users - and isn't informative at
> all. This commit changes it so that the error always says that there
> isn't debug information available, with these two variants:
>
> (gdb) list .
> Insufficient debug info for showing source lines at current PC (0x55555555511d).
> or
> (gdb) list .
> Insufficient debug info for showing source lines at default location.
>
> The difference now is if the inferior has started already, which is
> controlled by the user and may be useful.
>
> Unfortunately, it isn't as easy to differentiate if the symtab found for
> other list parameters is correct, so other invocations, such as "list +"
> still retain their original error message.
>
> Co-Authored-By: Simon Marchi <simark@simark.ca>
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
> ---
> Changes for v3:
> Changed error message to use Eli's suggestion
> Added Eli's RB tag since he approved documentation changes
>
> Changes for v2:
> Added NEWS entry, should have done that from the start oops.
> Added test. This test aims to roughly recreate a situation where the
> current function is in a spot with no debuginfo, and being called
> from somewhere that has debuginfo.
>
> ---
> gdb/NEWS | 6 ++
> gdb/cli/cli-cmds.c | 47 +++++++++----
> .../gdb.base/list-dot-nodebug-extra.c | 24 +++++++
> gdb/testsuite/gdb.base/list-dot-nodebug.c | 33 +++++++++
> gdb/testsuite/gdb.base/list-dot-nodebug.exp | 67 +++++++++++++++++++
> 5 files changed, 163 insertions(+), 14 deletions(-)
> create mode 100644 gdb/testsuite/gdb.base/list-dot-nodebug-extra.c
> create mode 100644 gdb/testsuite/gdb.base/list-dot-nodebug.c
> create mode 100644 gdb/testsuite/gdb.base/list-dot-nodebug.exp
>
> diff --git a/gdb/NEWS b/gdb/NEWS
> index feb3a37393a..99909414796 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -36,6 +36,12 @@ set unwindonsignal on|off
> show unwindonsignal
> These commands are now aliases for the new set/show unwind-on-signal.
>
> +list .
> + When using the command "list ." in a location that has no debug information
> + or no file loaded, GDB now says that there is no debug information to print
> + lines. This makes it more obvious that there is no information, as opposed
> + to implying there is no inferior loaded.
> +
> * New commands
>
> info missing-debug-handler
> diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
> index 3afe2178199..ee3318d7910 100644
> --- a/gdb/cli/cli-cmds.c
> +++ b/gdb/cli/cli-cmds.c
> @@ -1235,37 +1235,39 @@ list_command (const char *arg, int from_tty)
> /* Pull in the current default source line if necessary. */
> if (arg == NULL || ((arg[0] == '+' || arg[0] == '-' || arg[0] == '.') && arg[1] == '\0'))
> {
> - set_default_source_symtab_and_line ();
> - symtab_and_line cursal = get_current_source_symtab_and_line ();
> -
> /* If this is the first "list" since we've set the current
> source line, center the listing around that line. */
> if (get_first_line_listed () == 0 && (arg == nullptr || arg[0] != '.'))
> {
> - list_around_line (arg, cursal);
> + set_default_source_symtab_and_line ();
> + list_around_line (arg, get_current_source_symtab_and_line ());
> }
>
> /* "l" and "l +" lists the next few lines, unless we're listing past
> the end of the file. */
> else if (arg == nullptr || arg[0] == '+')
> {
> + set_default_source_symtab_and_line ();
> + const symtab_and_line cursal = get_current_source_symtab_and_line ();
> 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"));
> - }
> + 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. */
> else if (arg[0] == '-')
> {
> + set_default_source_symtab_and_line ();
> + const symtab_and_line cursal = get_current_source_symtab_and_line ();
> +
> if (get_first_line_listed () == 1)
> error (_("Already at the start of %s."),
> symtab_to_filename_for_display (cursal.symtab));
> +
> source_lines_range range (get_first_line_listed (),
> source_lines_range::BACKWARD);
> print_source_lines (cursal.symtab, range, 0);
> @@ -1274,25 +1276,42 @@ list_command (const char *arg, int from_tty)
> /* "list ." lists the default location again. */
> else if (arg[0] == '.')
> {
> + std::optional<const symtab_and_line> cursal;
I don't see why this needs to be a std::optional. Along both branches
of the following if/else we assign cursal a value.
Thanks,
Andrew
> if (target_has_stack ())
> {
> /* 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);
> + cursal.emplace (find_pc_line (curr_pc, 0));
> +
> + if (cursal->symtab == nullptr)
> + error
> + (_("Insufficient debug info for showing source lines at "
> + "current PC (%s)."), paddress (get_frame_arch (frame),
> + curr_pc));
> }
> else
> {
> /* The inferior is not running, so reset the current source
> location to the default (usually the main function). */
> clear_current_source_symtab_and_line ();
> - set_default_source_symtab_and_line ();
> - cursal = get_current_source_symtab_and_line ();
> + try
> + {
> + set_default_source_symtab_and_line ();
> + }
> + catch (const gdb_exception &e)
> + {
> + error (_("Insufficient debug info for showing source "
> + "lines at default location"));
> + }
> + cursal.emplace (get_current_source_symtab_and_line ());
> +
> + gdb_assert (cursal->symtab != nullptr);
> }
> - if (cursal.symtab == nullptr)
> - error (_("No debug information available to print source lines."));
> - list_around_line (arg, cursal);
> +
> + list_around_line (arg, *cursal);
> +
> /* Set the repeat args so just pressing "enter" after using "list ."
> will print the following lines instead of the same lines again. */
> if (from_tty)
> diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug-extra.c b/gdb/testsuite/gdb.base/list-dot-nodebug-extra.c
> new file mode 100644
> index 00000000000..c3d2416e70d
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/list-dot-nodebug-extra.c
> @@ -0,0 +1,24 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2024 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +extern void bar(int *);
> +
> +void
> +foo (int *x)
> +{
> + bar (x);
> +}
> diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.c b/gdb/testsuite/gdb.base/list-dot-nodebug.c
> new file mode 100644
> index 00000000000..b37c3561c41
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/list-dot-nodebug.c
> @@ -0,0 +1,33 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2024 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +extern void foo (int *x);
> +
> +int x;
> +
> +void
> +bar (int *p)
> +{
> + *p++;
> +}
> +
> +int
> +main ()
> +{
> + foo (&x);
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.base/list-dot-nodebug.exp b/gdb/testsuite/gdb.base/list-dot-nodebug.exp
> new file mode 100644
> index 00000000000..7c4144da8ab
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/list-dot-nodebug.exp
> @@ -0,0 +1,67 @@
> +# Copyright 2005-2024 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +# This test is here to confirm that the command "list ." will print the
> +# same message if GDB detects no debug information at all, or detects some
> +# but nothing for the current objfile.
> +
> +require !use_gdb_stub
> +
> +set linkflags [list additional_flags="-static"]
> +
> +if { ![gdb_can_simple_compile static-libc \
> + {
> + void main (void) { return 0; }
> + } \
> + executable $linkflags] } {
> + untested "Can't statically link"
> + return -1
> +}
> +
> +standard_testfile .c -extra.c
> +set objmainfile [standard_output_file ${testfile}-main.o]
> +set objextrafile [standard_output_file ${testfile}-extra.o]
> +
> +if {[gdb_compile "$srcdir/$subdir/$srcfile" $objmainfile object {nodebug}] != "" } {
> + untested "couldn't compile main file into object"
> + return -1
> +}
> +
> +foreach_with_prefix debug {"none" "some"} {
> +
> + set flags "nodebug"
> + if {$debug == "some"} {
> + set flags "debug"
> + }
> +
> + if {[prepare_for_testing_full "failed to prepare" \
> + [list ${testfile}-${debug} $linkflags \
> + $srcfile [list nodebug] \
> + $srcfile2 [list $debug]]]} {
> + return -1
> + }
> +
> + gdb_test "list ." \
> + "No debug information available to print source lines.*" \
> + "print before start"
> +
> + if { ![runto bar] } {
> + return -1
> + }
> +
> + gdb_test "list ." \
> + "No debug information available to print source lines at current PC.*" \
> + "print after start"
> +}
> --
> 2.44.0
More information about the Gdb-patches
mailing list