public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: Simon Marchi <simark@simark.ca>, gdb-patches@sourceware.org
Subject: Re: [PATCH] [gdb] Fix assert in delete_breakpoint
Date: Wed, 15 Nov 2023 12:12:30 +0100	[thread overview]
Message-ID: <ad47339b-e8b1-4cda-8c66-830919024ebf@suse.de> (raw)
In-Reply-To: <601592c1-4e19-42c8-bfd7-5671ef951ab3@simark.ca>

On 11/14/23 16:09, Simon Marchi wrote:
> On 11/13/23 10:26, Tom de Vries wrote:
>> On a pinebook (aarch64 with 64-bit kernel and 32-bit userland) with test-case
>> gdb.base/gdb-sigterm.exp I run into:
>> ...
>> intrusive_list.h:458: internal-error: erase_element: \
>>    Assertion `elem_node->prev != INTRUSIVE_LIST_UNLINKED_VALUE' failed.^M
>> ...
>>
>> Fix this similar to:
>> - commit c0afd99439f ("[gdb/tui] Fix assert in ~gdbpy_tui_window_maker"), and
>> - commit 995a34b1772 ("Guard against frame.c destructors running before
>>    frame-info.c's"
>> by checking is_linked () before attempting to remove from breakpoint_chain.
>>
>> Tested on the pinebook and x86_64-linux.
>>
>> PR gdb/31061
>> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31061
> 
> Hi Tom,
> 
> Did you dig a little bit to understand why this happened specifically
> with this setup, 

No, I just applied the usual recipe and observed that the problem was fixed.

But now that you asked, I did (and should have done of course).

> and that it's indeed expected that the breakpoint is
> not in the breakpoint chain?  The stack trace you showed contains (with
> names demangled):
> 
>      0xaae1d42b delete_breakpoint(breakpoint*)^M
>              /home/rock/gdb/src/gdb/breakpoint.c:12636^M
>      0xab1ed045 delete_thread_breakpoint^M
>              /home/rock/gdb/src/gdb/thread.c:98^M
>      0xab1ed0ab delete_single_step_breakpoints(thread_info*)^M
>              /home/rock/gdb/src/gdb/thread.c:123^M
>      0xab021e81 delete_thread_infrun_breakpoints^M
>              /home/rock/gdb/src/gdb/infrun.c:3733^M
>      0xab021edd for_each_just_stopped_thread^M
>              /home/rock/gdb/src/gdb/infrun.c:3752^M
>      0xab021f79 delete_just_stopped_threads_infrun_breakpoints^M
>              /home/rock/gdb/src/gdb/infrun.c:3768^M
> 
> It looks like this is specific to architectures that use software
> single stepping?  Does "32-bit userland on 64-bit kernel on aarch64" use
> software single stepping, like 32-bit ARM?
> 

System gdb is configured with --host=arm-linux-gnueabihf 
--target=arm-linux-gnueabihf (and I've copied that for my gdb build) so 
I suppose it's similar to 32-bit arm.

> Software single step breakpoints are inserted with:
> 
>    if (tp->control.single_step_breakpoints == NULL)
>      {
>        std::unique_ptr<breakpoint> b
> 	(new momentary_breakpoint (gdbarch, bp_single_step,
> 				   current_program_space,
> 				   null_frame_id,
> 				   tp->global_num));
> 
>        tp->control.single_step_breakpoints
> 	= add_to_breakpoint_chain (std::move (b));
>      }
> 
> They are added to the global breakpoint_chain by
> add_to_breakpoint_chain.  So how come the breakpoint is not linked when
> comes the time to delete it?

Because it's deleted twice.

The last thing we see in gdb.log before the internal error is:
...
    [infrun] handle_signal_stop: [13633.13633.0] hit its single-step 
breakpoint^M
...

And the statement following the infrun_debug_printf printing that 
message is:
...
   delete_just_stopped_threads_single_step_breakpoints ();
...

So, the following events happen:
- the single-step breakpoint is hit
- delete_just_stopped_threads_single_step_breakpoints is called
- during delete_just_stopped_threads_single_step_breakpoints,
   delete_breakpoint is called which removes the breakpoint from the
   breakpoint chain
- gdb is interrupted by SIGTERM before finish delete_breakpoint
- the SIGTERM triggers a SCOPE_EXIT cleanup, calling
   delete_just_stopped_threads_infrun_breakpoints which ends up
   calling delete_breakpoint again for the same breakpoint.

The proposed fix tries to handle delete_breakpoint being interrupted, 
and called again.

This is an alternative fix:
...
diff --git a/gdb/thread.c b/gdb/thread.c
index 47cc5c9cd14..7f029f2414c 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -93,11 +93,12 @@ inferior_thread (void)
  static void
  delete_thread_breakpoint (struct breakpoint **bp_p)
  {
-  if (*bp_p != NULL)
-    {
-      delete_breakpoint (*bp_p);
-      *bp_p = NULL;
-    }
+  struct breakpoint *bp = *bp_p;
+
+  *bp_p = nullptr;
+
+  if (bp != nullptr)
+    delete_breakpoint (bp);
  }

  void
...

It makes sure delete_breakpoint is called only once, but I don't think 
this is the way to go, since it prevents the cleanup.

Thanks,
- Tom

  reply	other threads:[~2023-11-15 11:10 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-13 15:26 Tom de Vries
2023-11-14 15:09 ` Simon Marchi
2023-11-15 11:12   ` Tom de Vries [this message]
2023-11-15 12:12     ` Tom de Vries
2023-11-21 12:22     ` Tom de Vries
2023-11-21 16:11     ` Simon Marchi
2023-11-21 16:52       ` Tom de Vries
2023-11-22 12:44         ` Tom de Vries
2023-11-22 14:49           ` Tom de Vries
2023-11-27 10:19           ` Tom de Vries
2023-11-27 16:29             ` Simon Marchi
2023-11-28 15:22               ` Tom de Vries
2023-11-28 15:30               ` Tom Tromey
2023-11-29 12:08                 ` Tom de Vries
2023-11-29 20:46                   ` Tom de Vries
2023-11-29 21:33                 ` Tom de Vries
2023-11-30 17:08                 ` Simon Marchi
2023-11-21 16:40   ` Luis Machado

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=ad47339b-e8b1-4cda-8c66-830919024ebf@suse.de \
    --to=tdevries@suse.de \
    --cc=gdb-patches@sourceware.org \
    --cc=simark@simark.ca \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).