Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: Tom Tromey <tom@tromey.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 1/2] [gdb] Fix sig_write for null gdb_stderr
Date: Wed, 30 Apr 2025 21:11:28 +0200	[thread overview]
Message-ID: <716d68d7-6888-4da6-a0e1-d8bf6c75f663@suse.de> (raw)
In-Reply-To: <dd0965f6-a805-4a99-b1a9-2b7bf7410be1@suse.de>

On 4/30/25 20:49, Tom de Vries wrote:
> On 4/29/25 17:34, Tom Tromey wrote:
>>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
>>
>> Tom> - gdbpy_flush attempts to flush gdb_stdout, which is nullptr
>> Tom> - that causes a segfault
>>
>> When can this be nullptr?
>> That seems surprising to me.
> 
> I managed to recognize the situation using:
> ...
> diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
> index 1b4cc82cce8..fa4186aea3b 100644
> --- a/gdb/tui/tui-io.c
> +++ b/gdb/tui/tui-io.c
> @@ -869,6 +869,7 @@ tui_setup_io (int mode)
>         /* Restore gdb output.  */
>         gdb_stdout = tui_old_stdout;
>         gdb_stderr = tui_old_stderr;
> +      gdb_assert (gdb_stderr != nullptr);
>         gdb_stdlog = tui_old_stdlog;
>         gdb_stdtarg = gdb_stderr;
>         current_uiout = tui_old_uiout;
> ...
> 
> And the backtrace (in an unusual form because of recursion) is:
> ...
> #19000 0x000000000041a3b2 in main (argc=14, argv=0x7ffc5c28c168)
>      at /data/vries/gdb/src/gdb/gdb.c:38
> 38      return gdb_main (&args);
> (gdb) down
> #18999 0x0000000000b68937 in gdb_main (args=0x7ffc5c28c030)
>      at /data/vries/gdb/src/gdb/main.c:1363
> 1363          captured_main (args);
> (gdb)
> #18998 0x0000000000b6888e in captured_main (data=0x7ffc5c28c030)
>      at /data/vries/gdb/src/gdb/main.c:1344
> 1344          captured_command_loop ();
> (gdb)
> #18997 0x0000000000b66dad in captured_command_loop ()
>      at /data/vries/gdb/src/gdb/main.c:466
> 466      start_event_loop ();
> (gdb)
> #18996 0x0000000000b66c21 in start_event_loop ()
>      at /data/vries/gdb/src/gdb/main.c:402
> 402          result = gdb_do_one_event ();
> (gdb)
> #18995 0x0000000001985e31 in gdb_do_one_event (mstimeout=-1)
>      at /data/vries/gdb/src/gdbsupport/event-loop.cc:263
> 263      return gdb_wait_for_event (1);
> (gdb)
> #18994 0x0000000001986f70 in gdb_wait_for_event (block=1)
>      at /data/vries/gdb/src/gdbsupport/event-loop.cc:672
> 672          handle_file_event (file_ptr, mask);
> (gdb)
> #18993 0x0000000001986995 in handle_file_event (file_ptr=0x3b26aff0,
>      ready_mask=25) at /data/vries/gdb/src/gdbsupport/event-loop.cc:551
> 551          file_ptr->proc (file_ptr->error, file_ptr->client_data);
> (gdb)
> #18992 0x00000000010563ad in stdin_event_handler (error=1,
>      client_data=0x3aec7120) at /data/vries/gdb/src/gdb/ui.c:128
> 128          quit_command ((char *) 0, 0);
> (gdb)
> #18991 0x00000000006b2e63 in quit_command (args=0x0, from_tty=0)
>      at /data/vries/gdb/src/gdb/cli/cli-cmds.c:483
> 483      quit_force (args ? &exit_code : NULL, from_tty);
> (gdb)
> #18990 0x0000000000fd94dc in quit_force (exit_arg=0x0, from_tty=0)
>      at /data/vries/gdb/src/gdb/top.c:1750
> 1750      undo_terminal_modifications_before_exit ();
> (gdb)
> #18989 0x0000000000fd942f in undo_terminal_modifications_before_exit ()
>      at /data/vries/gdb/src/gdb/top.c:1718
> 1718      tui_disable ();
> (gdb)
> #18988 0x000000000103fa11 in tui_disable ()
>      at /data/vries/gdb/src/gdb/tui/tui.c:562
> 562      tui_setup_io (0);
> (gdb)
> #18987 0x00000000010129d4 in tui_setup_io (mode=0)
>      at /data/vries/gdb/src/gdb/tui/tui-io.c:872
> 872          gdb_assert (gdb_stderr != nullptr);
> (gdb)
> ...

OK, I understand now how this happens.

The relevant code is in tui_enable.

While initializing, we set tui_active to true, because:
...
       /* We must mark the tui sub-system active before trying to setup
          the
          current layout as tui windows defined by an extension language 

          rely on this flag being true in order to know that the window 

          they are creating is currently valid.  */
       tui_active = true;
...

After that we call tui_set_initial_layout, and the DWARF error is thrown.

It's not caught early enough to continue executing tui_enable.

Consequently, tui_setup_io (1) is not called.

Then when undo_terminal_modifications_before_exit is called, it calls 
tui_disable, which checks for tui_active, and then calls setup_io (0) 
assuming setup_io (1) has been called, which is not the case.

Thanks,
- Tom


  reply	other threads:[~2025-04-30 19:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-25 17:18 [PATCH 0/2] [gdb] Fix error handling with nullptr gdb_stdout/gdb_stderr Tom de Vries
2025-04-25 17:18 ` [PATCH 1/2] [gdb] Fix sig_write for null gdb_stderr Tom de Vries
2025-04-28 15:17   ` Simon Marchi
2025-04-29 11:50     ` Tom de Vries
2025-04-29 15:34   ` Tom Tromey
2025-04-30 18:49     ` Tom de Vries
2025-04-30 19:11       ` Tom de Vries [this message]
2025-05-02 18:45         ` Tom Tromey
2025-04-25 17:18 ` [PATCH 2/2] [gdb] Handle nullptr stream in gdb_flush Tom de Vries
2025-04-28 15:21   ` Simon Marchi
2025-04-28 16:32     ` Tom de Vries
2025-04-28 16:38       ` Simon Marchi
2025-04-29 11:52         ` Tom de Vries

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=716d68d7-6888-4da6-a0e1-d8bf6c75f663@suse.de \
    --to=tdevries@suse.de \
    --cc=gdb-patches@sourceware.org \
    --cc=tom@tromey.com \
    /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