gdb/testsuite: make gdb.base/list-nodebug.exp pass without libc symbols

Message ID 20240130093029.170544-2-blarsen@redhat.com
State New
Headers
Series gdb/testsuite: make gdb.base/list-nodebug.exp pass without libc symbols |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm fail Testing failed

Commit Message

Guinevere Larsen Jan. 30, 2024, 9:30 a.m. UTC
  Simon noticed that the test gdb.base/list-nodebug.exp would fail if the
system doesn't have debug symbols for the standard library, and filed it
as PR gdb/31290. The issue is that, if GDB finds no symbols at all for,
it takes a different exit than if it finds some symbols, but nothing for
the current location.

This patch changes the test to accept any message, since the important
thing we're testing at this point is if GDB would crash, not what the
message is.
---
Email only:

I tried to condense the errors instead of changing the testcase, but I
couldn't find a good way to check if there were no symbols. My best
idea was to check if the symtab that was found has a linetable, and exit
error out if no linetable is present. However, I worry that a user may
want, for example, to list a specific function and I couldn't convince
myself that the linetable was required for that, so I decided to go this
safe route instead.

If the linetable is required, or it is at least reasonable ot require it
for listing a file, I can send the other patch instead.
---
 gdb/testsuite/gdb.base/list-nodebug.exp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
  

Comments

Simon Marchi Jan. 30, 2024, 4:34 p.m. UTC | #1
On 1/30/24 04:30, Guinevere Larsen wrote:
> Simon noticed that the test gdb.base/list-nodebug.exp would fail if the
> system doesn't have debug symbols for the standard library, and filed it
> as PR gdb/31290. The issue is that, if GDB finds no symbols at all for,
> it takes a different exit than if it finds some symbols, but nothing for
> the current location.
> 
> This patch changes the test to accept any message, since the important
> thing we're testing at this point is if GDB would crash, not what the
> message is.
> ---
> Email only:
> 
> I tried to condense the errors instead of changing the testcase, but I
> couldn't find a good way to check if there were no symbols. My best
> idea was to check if the symtab that was found has a linetable, and exit
> error out if no linetable is present. However, I worry that a user may
> want, for example, to list a specific function and I couldn't convince
> myself that the linetable was required for that, so I decided to go this
> safe route instead.
> 
> If the linetable is required, or it is at least reasonable ot require it
> for listing a file, I can send the other patch instead.

I guess what you are referring to here is what I complained about on
IRC, which is that without debug info for libc, we get:

    Breakpoint 1, 0x000055555555511d in main ()
    (gdb) list .
    No symbol table is loaded.  Use the "file" command.

and with debug info for libc, we get:

    Breakpoint 1, 0x000055555555511d in main ()
    (gdb) list .
    No debug information available to print source lines.

Note that in both cases, we don't have debug info for the objfile where
"main" is.  In the first case, we have zero debug info for the inferior,
and in the second case, we have some debug info for the inferior (for
libc), just not for the objfile containing "main".

My complaint is that the difference between these two cases isn't
relevant to the user, so I think the message printed should be the same
in both cases.  With "list .", the user asks to print the source lines
matching the current PC.  Having or not having debug info for libc
doesn't matter here.  The different messages are just the result of some
implementation details inside GDB.

(I would look into it, but I don't really have the time right now.)

If you agree with this, then perhaps you can keep the expected output
in the test (we would have to determine which output makes more sense),
but XFAIL the case that doesn't work as we want today.  At least, that
will leave a trace that something needs to be fixed.  I fear that by
just accepting .*, it will just get forgotten.

Simon
  
Guinevere Larsen Jan. 30, 2024, 4:48 p.m. UTC | #2
On 30/01/2024 17:34, Simon Marchi wrote:
> On 1/30/24 04:30, Guinevere Larsen wrote:
>> Simon noticed that the test gdb.base/list-nodebug.exp would fail if the
>> system doesn't have debug symbols for the standard library, and filed it
>> as PR gdb/31290. The issue is that, if GDB finds no symbols at all for,
>> it takes a different exit than if it finds some symbols, but nothing for
>> the current location.
>>
>> This patch changes the test to accept any message, since the important
>> thing we're testing at this point is if GDB would crash, not what the
>> message is.
>> ---
>> Email only:
>>
>> I tried to condense the errors instead of changing the testcase, but I
>> couldn't find a good way to check if there were no symbols. My best
>> idea was to check if the symtab that was found has a linetable, and exit
>> error out if no linetable is present. However, I worry that a user may
>> want, for example, to list a specific function and I couldn't convince
>> myself that the linetable was required for that, so I decided to go this
>> safe route instead.
>>
>> If the linetable is required, or it is at least reasonable ot require it
>> for listing a file, I can send the other patch instead.
> I guess what you are referring to here is what I complained about on
> IRC, which is that without debug info for libc, we get:
>
>      Breakpoint 1, 0x000055555555511d in main ()
>      (gdb) list .
>      No symbol table is loaded.  Use the "file" command.
>
> and with debug info for libc, we get:
>
>      Breakpoint 1, 0x000055555555511d in main ()
>      (gdb) list .
>      No debug information available to print source lines.
>
> Note that in both cases, we don't have debug info for the objfile where
> "main" is.  In the first case, we have zero debug info for the inferior,
> and in the second case, we have some debug info for the inferior (for
> libc), just not for the objfile containing "main".
>
> My complaint is that the difference between these two cases isn't
> relevant to the user, so I think the message printed should be the same
> in both cases.  With "list .", the user asks to print the source lines
> matching the current PC.  Having or not having debug info for libc
> doesn't matter here.  The different messages are just the result of some
> implementation details inside GDB.

Yes that's exactly what I was referring to. It was bothering me for 
longer than that, though.

My analysis of the problem is that list_command uses 
get_current_source_symtab_and_line, which will always return _some_ 
symtab if there are any to be found, and will error out otherwise. When 
it errors out (no libc debuginfo), we get the "No symbol table is 
loaded" message. When it doesn't (with libc debuginfo) it will return 
the symtab for libc, list_command will continue going and find the 
current symtab and line through find_pc_line, and if there is no symtab 
for the current we get the new error.

Catching the error from get_current_source_symtab_and_line doesn't sound 
too difficult, but I also wanted to avoid a situation where you try 
"list" in that situation and GDB attempts to print libc lines instead of 
main. I accidentally forgot that this wasn't part of what we talked 
about on IRC, oops. The difficulty comes from figuring out how we should 
figure out if the symtab that get_current_source_symtab_and_line returns 
the correct symtab, and one with debuginfo. My guess for checking if a 
symtab has debuginfo was to see if it has a linetable, but I wasn't sure 
if that was a correct assumption, and we still have the issue of a wrong 
symtab to deal with, which wasn't trivial.

Or I could also just try the simple try-catch I alluded to above and 
leave the scope creep to a future patch, I guess....

>
> (I would look into it, but I don't really have the time right now.)
>
> If you agree with this, then perhaps you can keep the expected output
> in the test (we would have to determine which output makes more sense),
> but XFAIL the case that doesn't work as we want today.  At least, that
> will leave a trace that something needs to be fixed.  I fear that by
> just accepting .*, it will just get forgotten.
Sure, I'll swap this patch to an XFAIL in that case for v2
  
Simon Marchi Jan. 30, 2024, 7:51 p.m. UTC | #3
On 1/30/24 11:48, Guinevere Larsen wrote:
> On 30/01/2024 17:34, Simon Marchi wrote:
>> On 1/30/24 04:30, Guinevere Larsen wrote:
>>> Simon noticed that the test gdb.base/list-nodebug.exp would fail if
>>> the system doesn't have debug symbols for the standard library, and
>>> filed it as PR gdb/31290. The issue is that, if GDB finds no symbols
>>> at all for, it takes a different exit than if it finds some symbols,
>>> but nothing for the current location.
>>>
>>> This patch changes the test to accept any message, since the
>>> important thing we're testing at this point is if GDB would crash,
>>> not what the message is.  --- Email only:
>>>
>>> I tried to condense the errors instead of changing the testcase, but
>>> I couldn't find a good way to check if there were no symbols. My
>>> best idea was to check if the symtab that was found has a linetable,
>>> and exit error out if no linetable is present. However, I worry that
>>> a user may want, for example, to list a specific function and I
>>> couldn't convince myself that the linetable was required for that,
>>> so I decided to go this safe route instead.
>>>
>>> If the linetable is required, or it is at least reasonable ot
>>> require it for listing a file, I can send the other patch instead.
>> I guess what you are referring to here is what I complained about on
>> IRC, which is that without debug info for libc, we get:
>>
>>      Breakpoint 1, 0x000055555555511d in main () (gdb) list .  No
>>      symbol table is loaded.  Use the "file" command.
>>
>> and with debug info for libc, we get:
>>
>>      Breakpoint 1, 0x000055555555511d in main () (gdb) list .  No
>>      debug information available to print source lines.
>>
>> Note that in both cases, we don't have debug info for the objfile
>> where "main" is.  In the first case, we have zero debug info for the
>> inferior, and in the second case, we have some debug info for the
>> inferior (for libc), just not for the objfile containing "main".
>>
>> My complaint is that the difference between these two cases isn't
>> relevant to the user, so I think the message printed should be the
>> same in both cases.  With "list .", the user asks to print the source
>> lines matching the current PC.  Having or not having debug info for
>> libc doesn't matter here.  The different messages are just the result
>> of some implementation details inside GDB.
> 
> Yes that's exactly what I was referring to. It was bothering me for
> longer than that, though.
> 
> My analysis of the problem is that list_command uses
> get_current_source_symtab_and_line, which will always return _some_
> symtab if there are any to be found, and will error out otherwise.
> When it errors out (no libc debuginfo), we get the "No symbol table is
> loaded" message. When it doesn't (with libc debuginfo) it will return
> the symtab for libc, list_command will continue going and find the
> current symtab and line through find_pc_line, and if there is no
> symtab for the current we get the new error.
> 
> Catching the error from get_current_source_symtab_and_line doesn't
> sound too difficult, but I also wanted to avoid a situation where you
> try "list" in that situation and GDB attempts to print libc lines
> instead of main. I accidentally forgot that this wasn't part of what
> we talked about on IRC, oops. The difficulty comes from figuring out
> how we should figure out if the symtab that
> get_current_source_symtab_and_line returns the correct symtab, and one
> with debuginfo. My guess for checking if a symtab has debuginfo was to
> see if it has a linetable, but I wasn't sure if that was a correct
> assumption, and we still have the issue of a wrong symtab to deal
> with, which wasn't trivial.

What I was wondering when looking at it the other day is: why do we need
to call get_current_source_symtab_and_line at all in a case where we
don't care about the "current" location?

Early in the function, we have:

  symtab_and_line cursal = get_current_source_symtab_and_line ();

But in the `else if (arg[0] == '.')` portion of the function, it looks
like we override `cursal` with something else.  So, it is possible to
call get_current_source_symtab_and_line only in the scopes that actually
require it?

Simon
  
Guinevere Larsen Jan. 31, 2024, 2:49 p.m. UTC | #4
On 30/01/2024 20:51, Simon Marchi wrote:
> On 1/30/24 11:48, Guinevere Larsen wrote:
>> On 30/01/2024 17:34, Simon Marchi wrote:
>>> On 1/30/24 04:30, Guinevere Larsen wrote:
>>>> Simon noticed that the test gdb.base/list-nodebug.exp would fail if
>>>> the system doesn't have debug symbols for the standard library, and
>>>> filed it as PR gdb/31290. The issue is that, if GDB finds no symbols
>>>> at all for, it takes a different exit than if it finds some symbols,
>>>> but nothing for the current location.
>>>>
>>>> This patch changes the test to accept any message, since the
>>>> important thing we're testing at this point is if GDB would crash,
>>>> not what the message is.  --- Email only:
>>>>
>>>> I tried to condense the errors instead of changing the testcase, but
>>>> I couldn't find a good way to check if there were no symbols. My
>>>> best idea was to check if the symtab that was found has a linetable,
>>>> and exit error out if no linetable is present. However, I worry that
>>>> a user may want, for example, to list a specific function and I
>>>> couldn't convince myself that the linetable was required for that,
>>>> so I decided to go this safe route instead.
>>>>
>>>> If the linetable is required, or it is at least reasonable ot
>>>> require it for listing a file, I can send the other patch instead.
>>> I guess what you are referring to here is what I complained about on
>>> IRC, which is that without debug info for libc, we get:
>>>
>>>       Breakpoint 1, 0x000055555555511d in main () (gdb) list .  No
>>>       symbol table is loaded.  Use the "file" command.
>>>
>>> and with debug info for libc, we get:
>>>
>>>       Breakpoint 1, 0x000055555555511d in main () (gdb) list .  No
>>>       debug information available to print source lines.
>>>
>>> Note that in both cases, we don't have debug info for the objfile
>>> where "main" is.  In the first case, we have zero debug info for the
>>> inferior, and in the second case, we have some debug info for the
>>> inferior (for libc), just not for the objfile containing "main".
>>>
>>> My complaint is that the difference between these two cases isn't
>>> relevant to the user, so I think the message printed should be the
>>> same in both cases.  With "list .", the user asks to print the source
>>> lines matching the current PC.  Having or not having debug info for
>>> libc doesn't matter here.  The different messages are just the result
>>> of some implementation details inside GDB.
>> Yes that's exactly what I was referring to. It was bothering me for
>> longer than that, though.
>>
>> My analysis of the problem is that list_command uses
>> get_current_source_symtab_and_line, which will always return _some_
>> symtab if there are any to be found, and will error out otherwise.
>> When it errors out (no libc debuginfo), we get the "No symbol table is
>> loaded" message. When it doesn't (with libc debuginfo) it will return
>> the symtab for libc, list_command will continue going and find the
>> current symtab and line through find_pc_line, and if there is no
>> symtab for the current we get the new error.
>>
>> Catching the error from get_current_source_symtab_and_line doesn't
>> sound too difficult, but I also wanted to avoid a situation where you
>> try "list" in that situation and GDB attempts to print libc lines
>> instead of main. I accidentally forgot that this wasn't part of what
>> we talked about on IRC, oops. The difficulty comes from figuring out
>> how we should figure out if the symtab that
>> get_current_source_symtab_and_line returns the correct symtab, and one
>> with debuginfo. My guess for checking if a symtab has debuginfo was to
>> see if it has a linetable, but I wasn't sure if that was a correct
>> assumption, and we still have the issue of a wrong symtab to deal
>> with, which wasn't trivial.
> What I was wondering when looking at it the other day is: why do we need
> to call get_current_source_symtab_and_line at all in a case where we
> don't care about the "current" location?

"current" is a poorly defined term in this context. what the `.` 
argument means with "current" is point of execution of the inferior, 
what get_current_source_symtab_and_line means by "current" is the 
location that is being printed.

I say this based on the fact that list with no arguments or with '+' use 
this "current" sal to continue printing the file.

>
> Early in the function, we have:
>
>    symtab_and_line cursal = get_current_source_symtab_and_line ();
>
> But in the `else if (arg[0] == '.')` portion of the function, it looks
> like we override `cursal` with something else.  So, it is possible to
> call get_current_source_symtab_and_line only in the scopes that actually
> require it?

As I mentioned, this gets used by no arg and '+', but I'm not sure if it 
is necessary. We can define cursal only when first printing and for '.', 
using get_last_line_printed for the rest.

That's besides the point, the important part is that this is the only 
location (other than '.' recently added) that is able to tell if the 
inferior has debuginfo, so we have to handle its error somewhere if we 
want to have a single message for all list errors.

> Simon
>
  
Simon Marchi Jan. 31, 2024, 9:18 p.m. UTC | #5
On 1/31/24 09:49, Guinevere Larsen wrote:
> On 30/01/2024 20:51, Simon Marchi wrote:
>> On 1/30/24 11:48, Guinevere Larsen wrote:
>> What I was wondering when looking at it the other day is: why do we
>> need to call get_current_source_symtab_and_line at all in a case
>> where we don't care about the "current" location?
> 
> "current" is a poorly defined term in this context. what the `.`
> argument means with "current" is point of execution of the inferior,
> what get_current_source_symtab_and_line means by "current" is the
> location that is being printed.
> 
> I say this based on the fact that list with no arguments or with '+'
> use this "current" sal to continue printing the file.

Right, but "list ." does not the "current sal".  I said "why do we need
to call get_current_source_symtab_and_line", but in fact it's
"set_default_source_symtab_and_line" that throws the exception, so it's
"set_default_source_symtab_and_line" that we should avoid calling if we
are not going to use it.

>> Early in the function, we have:
>>
>>    symtab_and_line cursal = get_current_source_symtab_and_line ();
>>
>> But in the `else if (arg[0] == '.')` portion of the function, it
>> looks like we override `cursal` with something else.  So, it is
>> possible to call get_current_source_symtab_and_line only in the
>> scopes that actually require it?
> 
> As I mentioned, this gets used by no arg and '+', but I'm not sure if
> it is necessary. We can define cursal only when first printing and for
> '.', using get_last_line_printed for the rest.
> 
> That's besides the point, the important part is that this is the only
> location (other than '.' recently added) that is able to tell if the
> inferior has debuginfo, so we have to handle its error somewhere if we
> want to have a single message for all list errors.

I wrote the patch below to illustrate what I mean.  With it, I at least
get the same message for "list ." on the list-nodebug executable,
regardless of if I have libc debug symbols or not:

    (gdb) list .
    No debug information available to print source lines at current PC (0x55555555511d).

It is still different than if I use "list +", with no debug symbols:

    (gdb) list +
    No symbol table is loaded.  Use the "file" command.

Perhaps that's still not ideal, I don't know, but I think it's already
better than having two different messages for "list .", based on some
unrelated variable (the presence of some debug info for another part of
the program).

Simon

From 292d16f94423758bb08cd14209941a92218878c0 Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@efficios.com>
Date: Wed, 31 Jan 2024 14:18:59 -0500
Subject: [PATCH] Test change to list_command

Change-Id: Ia536108a0c69d105cb3c6868c53afb12bb9c4ba9
---
 gdb/cli/cli-cmds.c | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index df11f956245c..1df632594e8e 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1236,37 +1236,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);
@@ -1275,13 +1277,19 @@ 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;
 	  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
+		  (_("No debug information available to print source lines at current PC (%s)."),
+		   paddress (get_frame_arch (frame), curr_pc));
 	    }
 	  else
 	    {
@@ -1289,11 +1297,14 @@ list_command (const char *arg, int from_tty)
 		 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 ();
+	      cursal.emplace (get_current_source_symtab_and_line ());
+
+	      // Not sure if always true, just guessing.
+	      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)

base-commit: 249e54204b13f9acdd5fbca355fed305e8595f31
  
Guinevere Larsen Feb. 2, 2024, 11:05 a.m. UTC | #6
On 31/01/2024 22:18, Simon Marchi wrote:
> On 1/31/24 09:49, Guinevere Larsen wrote:
>> On 30/01/2024 20:51, Simon Marchi wrote:
>>> On 1/30/24 11:48, Guinevere Larsen wrote:
>>> What I was wondering when looking at it the other day is: why do we
>>> need to call get_current_source_symtab_and_line at all in a case
>>> where we don't care about the "current" location?
>> "current" is a poorly defined term in this context. what the `.`
>> argument means with "current" is point of execution of the inferior,
>> what get_current_source_symtab_and_line means by "current" is the
>> location that is being printed.
>>
>> I say this based on the fact that list with no arguments or with '+'
>> use this "current" sal to continue printing the file.
> Right, but "list ." does not the "current sal".  I said "why do we need
> to call get_current_source_symtab_and_line", but in fact it's
> "set_default_source_symtab_and_line" that throws the exception, so it's
> "set_default_source_symtab_and_line" that we should avoid calling if we
> are not going to use it.
>
>>> Early in the function, we have:
>>>
>>>     symtab_and_line cursal = get_current_source_symtab_and_line ();
>>>
>>> But in the `else if (arg[0] == '.')` portion of the function, it
>>> looks like we override `cursal` with something else.  So, it is
>>> possible to call get_current_source_symtab_and_line only in the
>>> scopes that actually require it?
>> As I mentioned, this gets used by no arg and '+', but I'm not sure if
>> it is necessary. We can define cursal only when first printing and for
>> '.', using get_last_line_printed for the rest.
>>
>> That's besides the point, the important part is that this is the only
>> location (other than '.' recently added) that is able to tell if the
>> inferior has debuginfo, so we have to handle its error somewhere if we
>> want to have a single message for all list errors.
> I wrote the patch below to illustrate what I mean.  With it, I at least
> get the same message for "list ." on the list-nodebug executable,
> regardless of if I have libc debug symbols or not:
>
>      (gdb) list .
>      No debug information available to print source lines at current PC (0x55555555511d).
>
> It is still different than if I use "list +", with no debug symbols:
>
>      (gdb) list +
>      No symbol table is loaded.  Use the "file" command.
>
> Perhaps that's still not ideal, I don't know, but I think it's already
> better than having two different messages for "list .", based on some
> unrelated variable (the presence of some debug info for another part of
> the program).
This still has 2 different errors, if a user tries "list ." before 
starting the inferior. This is because we also hit the same error in 
set_default_symtab_and_line further down, when we check if a target 
doesn't have a stack.

I have attempted to fix it inline, but I'm not really happy with it yet, 
I just ran out of time due to FOSDEM and a week of vacation.

>
> Simon
>
>  From 292d16f94423758bb08cd14209941a92218878c0 Mon Sep 17 00:00:00 2001
> From: Simon Marchi <simon.marchi@efficios.com>
> Date: Wed, 31 Jan 2024 14:18:59 -0500
> Subject: [PATCH] Test change to list_command
>
> Change-Id: Ia536108a0c69d105cb3c6868c53afb12bb9c4ba9
> ---
>   gdb/cli/cli-cmds.c | 37 ++++++++++++++++++++++++-------------
>   1 file changed, 24 insertions(+), 13 deletions(-)
>
> diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
> index df11f956245c..1df632594e8e 100644
> --- a/gdb/cli/cli-cmds.c
> +++ b/gdb/cli/cli-cmds.c
> @@ -1236,37 +1236,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 ());

By applying this change here:

          source line, center the listing around that line. */
-      if (get_first_line_listed () == 0 && (arg == nullptr || arg[0] != 
'.'))
+      if (get_first_line_listed () == 0)
{
-         set_default_source_symtab_and_line ();
+ try
+ {
+             set_default_source_symtab_and_line ();
+ }
+         catch (const gdb_exception &e)
+ {
+             error (_("No debug information available to "
+                      "print source lines at current PC"));
+ }
           list_around_line (arg, get_current_source_symtab_and_line ());
}

we get a single error for all list commands if there are absolutely no 
symtabs (which is what happens if the inferior hasn't started) and we 
get a single error with "list ." I'm not a fan of "current PC" when the 
inferior may not be executing,though.

And with this change, we don't need a try_catch around the other 
set_default_symtab_and_line because we'll only reach it if we managed to 
print something before... I think, but i'm not sure.
  

Patch

diff --git a/gdb/testsuite/gdb.base/list-nodebug.exp b/gdb/testsuite/gdb.base/list-nodebug.exp
index 08de05423af..df2761f89e4 100644
--- a/gdb/testsuite/gdb.base/list-nodebug.exp
+++ b/gdb/testsuite/gdb.base/list-nodebug.exp
@@ -30,8 +30,8 @@  if {![runto_main]} {
 
 # Check that GDB doesn't crash when we use list . on an inferior with
 # no debug information
-gdb_test "list ." "No debug.*" "first 'list .'"
+gdb_test "list ." ".*" "first 'list .'"
 # This should be called twice because the first list invocation since
 # printing a frame may take a different codepath, which wouldn't
 # trigger the crash.
-gdb_test "list ." "No debug.*" "second 'list .'"
+gdb_test "list ." ".*" "second 'list .'"