Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: Andrew Burgess <aburgess@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH] [gdb/tui] Don't show incorrect source file in source window
Date: Wed, 29 Jan 2025 13:44:47 +0100	[thread overview]
Message-ID: <304fb3ec-74f9-4544-b9a7-3c4ed05e28bf@suse.de> (raw)
In-Reply-To: <3e18503c-2048-4ff8-8ba2-18eb51337b5f@suse.de>

On 1/29/25 13:27, Tom de Vries wrote:
> On 1/29/25 12:25, Andrew Burgess wrote:
>> Tom de Vries <tdevries@suse.de> writes:
>>
>>> Consider the test-case sources main.c and foo.c:
>>> ...
>>> $ cat main.c
>>> extern int foo (void);
>>>
>>> int
>>> main (void)
>>> {
>>>    return foo ();
>>> }
>>> $ cat foo.c
>>> extern int foo (void);
>>>
>>> int
>>> foo (void)
>>> {
>>>    return 0;
>>> }
>>> ...
>>> and main.c compiled with debug info, and foo.c without:
>>> ...
>>> $ gcc -g main.c -c
>>> $ gcc foo.c -c
>>> $ gcc -g main.o foo.o
>>> ...
>>>
>>> In TUI mode, if we run to foo:
>>> ...
>>> $ gdb -q a.out -tui -ex "b foo" -ex run
>>> ...
>>> it gets us "[ No Source Available ]":
>>> ...
>>> ┌─main.c─────────────────────────────────────────┐
>>> │                                                │
>>> │                                                │
>>> │                                                │
>>> │            [ No Source Available ]             │
>>> │                                                │
>>> │                                                │
>>> └────────────────────────────────────────────────┘
>>> (src) In: foo                  L??   PC: 0x400566
>>> db.so.1".
>>>
>>> Breakpoint 1, 0x0000000000400566 in foo ()
>>> (gdb)
>>> ...
>>>
>>> But after resizing (pressing ctrl-<minus> in the gnome-terminal), we get
>>> instead the source for main.c:
>>> ...
>>> ┌─main.c───────────────────────────────────────────────────┐
>>> │        3 int                                             │
>>> │        4 main (void)                                     │
>>> │        5 {                                               │
>>> │        6   return foo ();                                │
>>> │        7 }                                               │
>>> │                                                          │
>>> │                                                          │
>>> └──────────────────────────────────────────────────────────┘
>>> (src) In: foo                            L??   PC: 0x400566
>>> db.so.1".
>>>
>>> Breakpoint 1, 0x0000000000400566 in foo ()
>>> (gdb)
>>> ...
>>> which is inappropriate because we're stopped in function foo, which 
>>> is not in
>>> main.c.
>>>
>>> Fix this in tui_source_window_base::rerender.
>>>
>>> Tested on x86_64-linux.
>>>
>>> Reported-By: Andrew Burgess <aburgess@redhat.com>
>>>
>>> PR tui/32614
>>> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32614
>>> ---
>>>   gdb/testsuite/gdb.tui/resize-3-foo.c  | 24 ++++++++++
>>>   gdb/testsuite/gdb.tui/resize-3-main.c | 24 ++++++++++
>>>   gdb/testsuite/gdb.tui/resize-3.exp    | 63 +++++++++++++++++++++++++++
>>>   gdb/tui/tui-winsource.c               |  6 +++
>>>   4 files changed, 117 insertions(+)
>>>   create mode 100644 gdb/testsuite/gdb.tui/resize-3-foo.c
>>>   create mode 100644 gdb/testsuite/gdb.tui/resize-3-main.c
>>>   create mode 100644 gdb/testsuite/gdb.tui/resize-3.exp
>>>
>>> diff --git a/gdb/testsuite/gdb.tui/resize-3-foo.c b/gdb/testsuite/ 
>>> gdb.tui/resize-3-foo.c
>>> new file mode 100644
>>> index 00000000000..653b24ba92b
>>> --- /dev/null
>>> +++ b/gdb/testsuite/gdb.tui/resize-3-foo.c
>>> @@ -0,0 +1,24 @@
>>> +/* This testcase is part of GDB, the GNU debugger.
>>> +
>>> +   Copyright 2025 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 int foo (void);
>>> +
>>> +int
>>> +foo (void)
>>> +{
>>> +  return 0;
>>> +}
>>> diff --git a/gdb/testsuite/gdb.tui/resize-3-main.c b/gdb/testsuite/ 
>>> gdb.tui/resize-3-main.c
>>> new file mode 100644
>>> index 00000000000..95fdd3b6ba0
>>> --- /dev/null
>>> +++ b/gdb/testsuite/gdb.tui/resize-3-main.c
>>> @@ -0,0 +1,24 @@
>>> +/* This testcase is part of GDB, the GNU debugger.
>>> +
>>> +   Copyright 2025 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 int foo (void);
>>> +
>>> +int
>>> +main (void)
>>> +{
>>> +  return foo ();
>>> +}
>>> diff --git a/gdb/testsuite/gdb.tui/resize-3.exp b/gdb/testsuite/ 
>>> gdb.tui/resize-3.exp
>>> new file mode 100644
>>> index 00000000000..ec022b4a177
>>> --- /dev/null
>>> +++ b/gdb/testsuite/gdb.tui/resize-3.exp
>>> @@ -0,0 +1,63 @@
>>> +# Copyright 2025 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/>.
>>> +
>>> +# Test TUI resizing while showing "No Source Available".
>>> +
>>> +require allow_tui_tests
>>> +
>>> +standard_testfile -main.c -foo.c
>>> +
>>> +if { [build_executable_from_specs "failed to prepare" \
>>> +      $testfile {debug} \
>>> +      $srcfile {debug} \
>>> +      $srcfile2 {nodebug}] == -1 } {
>>> +    return -1
>>> +}
>>> +
>>> +tuiterm_env
>>> +
>>> +Term::clean_restart 24 80 $testfile
>>> +
>>> +# It would be simpler to run directly to foo and then enter TUI, but 
>>> that
>>> +# fails to trigger PR32614.  So instead, we first run to main, enter 
>>> TUI and
>>> +# then run to foo.
>>> +if {![runto_main]} {
>>> +    perror "test suppressed"
>>> +    return
>>> +}
>>> +
>>> +# Set a breakpoint on foo, easier to do before entering TUI.
>>> +gdb_breakpoint foo
>>> +
>>> +if {![Term::enter_tui]} {
>>> +    unsupported "TUI not supported"
>>> +    return
>>> +}
>>> +
>>> +# Continue to foo.
>>> +Term::command continue
>>> +
>>> +with_test_prefix "before resize" {
>>> +    Term::check_contents "Source window empty" \
>>> +    "No Source Available"
>>> +}
>>> +
>>> +Term::resize 40 90
>>> +
>>> +with_test_prefix "after resize" {
>>> +    # Regression test for PR32614.
>>> +    Term::check_contents "Source window empty" \
>>> +    "No Source Available"
>>> +}
>>> diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
>>> index a5d0c594545..bf4052755df 100644
>>> --- a/gdb/tui/tui-winsource.c
>>> +++ b/gdb/tui/tui-winsource.c
>>> @@ -460,6 +460,12 @@ tui_source_window_base::rerender ()
>>>         struct gdbarch *gdbarch = get_frame_arch (frame);
>>>         struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
>>> +      if (s == nullptr)
>>> +    {
>>> +      erase_source_content ();
>>> +      return;
>>> +    }
>>
>> This didn't look quite right to me.  But while trying to find the set of
>> steps to show why I don't think this change is exactly right ... I ran
>> into another bug, which means that this isn't wrong right now ... but
>> might be once the other bug is fixed ... maybe ....
>>
>> So, what worried me, is that this ::rerender is called for both the SRC
>> window and the ASM window.  My thinking was that if this change is
>> fixing things so we call erase_source_content() when we cannot find the
>> source file, then we're also going to call erase_source_content() for
>> the ASM window when we cannot find the source file, and that cannot be
>> right, we should always be able to update the ASM window with the
>> correct disassembler output.
>>
> 
> Hi Andrew,
> 
> thanks for the review, and bringing up this point.
> 
> I've submitted a v2 that limits the impact of the fix to the source 
> window ( https://sourceware.org/pipermail/gdb-patches/2025- 
> January/215043.html ).
> 
>> So I tried the following with an UNPATCHED gdb:
>>
>>    1. layout src
>>    2. step into a region where "No Source Available" is shown.
>>    3. layout asm
>>
>> My expectation is that I should immediately see the disassembler output
>> for the current $pc location.  What I actually see is "No Assembly
>> Available".
>>
> 
> I can reproduce this.
> 

FWIW, I investigated this as well, and tried to make a similar minimal 
fix, and ended up with:
...
diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
index a5d0c594545..07aca28eb53 100644
--- a/gdb/tui/tui-winsource.c
+++ b/gdb/tui/tui-winsource.c
@@ -459,9 +459,11 @@ tui_source_window_base::rerender ()
        frame_info_ptr frame = deprecated_safe_get_selected_frame ();
        struct gdbarch *gdbarch = get_frame_arch (frame);

-      struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
        if (this != tui_src_win ())
-	find_line_pc (s, cursal.line, &cursal.pc);
+	{
+	  update_source_window_with_addr (gdbarch, get_frame_pc (frame));
+	  return;
+	}

        /* This centering code is copied from 
tui_source_window::maybe_update.
...

Thanks,
- Tom

>> Turns out we hit the erase_source_content() call in
>> tui_source_window_base::update_source_window_as_is because the sal.pc
>> within that function is 0, and so the set_contents call returns false.
>>
>> If I then `si` the ASM window immediately updates with the disassembler
>> output.  This time the update originates from tui_show_frame_info, which
>> gets the symtab_and_line via a different approach than the ::rerender
>> function does.
>>
>> So I wondered, would a better solution be to rewrite at least part of
>> ::rerender based on tui_show_frame_info?
>>
>> Below is a _rough_ patch which does just this.  There's no commit
>> message or anything yet.  It passes all the gdb.tui/ tests, including
>> your new test that you added with this patch.
>>
>> This also seems to resolve the src -> asm switching issue I detail
>> above.
>>
>> I'd love to hear what you think about this approach.
>>
> 
> I like it because it make the resulting code much shorter, and straight- 
> line code.
> 
> Superficially it doesn't look wrong to me, but unfortunately, my 
> understanding of the TUI code is not sufficient to approve or even 
> review it.
> 
> FWIW, it would be good to known whether all the paths in the old code 
> are covered by the test-suite.
> 
>> If you think this is the way to go then I'd propose that I write this
>> up, steal your new test, and add another test to expose the src to asm
>> switching issue.
>>
> 
> We could do that, or go with the v2 I proposed (if that is indeed 
> acceptable) and work from there.  I have a very slight preference for 
> the latter.
> 
> Thanks,
> - Tom
> 
>> But I'm worried that I might be missing something.
>>
>> Thanks,
>> Andrew
>>
>> ---
>>
>> diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
>> index a5d0c594545..b9c26e88a3a 100644
>> --- a/gdb/tui/tui-winsource.c
>> +++ b/gdb/tui/tui-winsource.c
>> @@ -454,25 +454,10 @@ tui_source_window_base::rerender ()
>>       }
>>     else if (deprecated_safe_get_selected_frame () != NULL)
>>       {
>> -      symtab_and_line cursal
>> -    = get_current_source_symtab_and_line (current_program_space);
>>         frame_info_ptr frame = deprecated_safe_get_selected_frame ();
>> -      struct gdbarch *gdbarch = get_frame_arch (frame);
>> -
>> -      struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
>> -      if (this != tui_src_win ())
>> -    find_line_pc (s, cursal.line, &cursal.pc);
>> -
>> -      /* This centering code is copied from 
>> tui_source_window::maybe_update.
>> -     It would be nice to do centering more often, and do it in just one
>> -     location.  But since this is a regression fix, handle this
>> -     conservatively for now.  */
>> -      int start_line = (cursal.line - ((height - box_size ()) / 2)) + 1;
>> -      if (start_line <= 0)
>> -    start_line = 1;
>> -      cursal.line = start_line;
>> -
>> -      update_source_window (gdbarch, cursal);
>> +      symtab_and_line cursal = find_frame_sal (frame);
>> +
>> +      maybe_update (frame, cursal);
>>       }
>>     else
>>       {
> 


      reply	other threads:[~2025-01-29 12:45 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-29 10:21 Tom de Vries
2025-01-29 11:25 ` Andrew Burgess
2025-01-29 12:27   ` Tom de Vries
2025-01-29 12:44     ` Tom de Vries [this message]

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=304fb3ec-74f9-4544-b9a7-3c4ed05e28bf@suse.de \
    --to=tdevries@suse.de \
    --cc=aburgess@redhat.com \
    --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