From: Simon Marchi <simark@simark.ca>
To: Andrew Burgess <aburgess@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH] gdb: ensure bp_location::section is set correct to avoid an assert
Date: Thu, 4 Sep 2025 23:10:31 -0400 [thread overview]
Message-ID: <c22f2178-85da-47f7-b103-2e54bbeff5ed@simark.ca> (raw)
In-Reply-To: <6ebdf11970be5450d222e5d3af746671136ed57d.1757016971.git.aburgess@redhat.com>
On 2025-09-04 16:16, Andrew Burgess wrote:
> While reviewing and testing another patch I set a breakpoint on an
> gnu ifunc function, then restarted the inferior, and this assert
> triggered:
>
> ../../src/gdb/breakpoint.c:14747: internal-error: breakpoint_free_objfile: Assertion `loc->symtab == nullptr' failed.
>
> The backtrace at the time of the assert is:
>
> #6 0x00000000005ffee0 in breakpoint_free_objfile (objfile=0x4064b30) at ../../src/gdb/breakpoint.c:14747
> #7 0x0000000000c33ff2 in objfile::~objfile (this=0x4064b30, __in_chrg=<optimized out>) at ../../src/gdb/objfiles.c:478
> #8 0x0000000000c38da6 in std::default_delete<objfile>::operator() (this=0x7ffc1a49d538, __ptr=0x4064b30) at /usr/include/c++/9/bits/unique_ptr.h:81
> #9 0x0000000000c3782a in std::unique_ptr<objfile, std::default_delete<objfile> >::~unique_ptr (this=0x7ffc1a49d538, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/unique_ptr.h:292
> #10 0x0000000000caf1bd in owning_intrusive_list<objfile, intrusive_base_node<objfile> >::erase (this=0x3790d68, i=...) at ../../src/gdb/../gdbsupport/owning_intrusive_list.h:111
> #11 0x0000000000cacd0c in program_space::remove_objfile (this=0x3790c80, objfile=0x4064b30) at ../../src/gdb/progspace.c:192
> #12 0x0000000000c33e1c in objfile::unlink (this=0x4064b30) at ../../src/gdb/objfiles.c:408
> #13 0x0000000000c34fb9 in objfile_purge_solibs (pspace=0x3790c80) at ../../src/gdb/objfiles.c:729
> #14 0x0000000000edf6f7 in no_shared_libraries (pspace=0x3790c80) at ../../src/gdb/solib.c:1359
> #15 0x0000000000fb3f6c in target_pre_inferior () at ../../src/gdb/target.c:2466
> #16 0x0000000000a724d7 in run_command_1 (args=0x0, from_tty=0, run_how=RUN_NORMAL) at ../../src/gdb/infcmd.c:390
> #17 0x0000000000a72a97 in run_command (args=0x0, from_tty=0) at ../../src/gdb/infcmd.c:514
> #18 0x00000000006bbb3d in do_simple_func (args=0x0, from_tty=0, c=0x39124b0) at ../../src/gdb/cli/cli-decode.c:95
> #19 0x00000000006c1021 in cmd_func (cmd=0x39124b0, args=0x0, from_tty=0) at ../../src/gdb/cli/cli-decode.c:2827
>
> The function breakpoint_free_objfile is being called when an objfile
> representing a shared library is being unloaded ahead of the inferior
> being restarted, the function is trying to remove references to
> anything that could itself reference the objfile that is being
> deleted.
>
> The assert is making the claim that, for a bp_location, which has a
> single address, the objfile of the symtab associated with the location
> will be the same as the objfile associated with the section of the
> location.
>
> This seems reasonable to me now, as it did when I added the assert in
> commit:
>
> commit 5066f3680667ec0f2d1745847a2372d85973a1e7
> Date: Mon Nov 11 21:45:17 2024 +0000
>
> gdb: do better in breakpoint_free_objfile
>
> The bp_location::section is maintained, according to the comments in
> breakpoint.h, to aid overlay debugging (is that even used any more),
> and looking at the code, this does appear to be the case.
>
> The problem in the above case arises when we are dealing with an ifunc
> function. What happens is that we end up with a section from one
> objfile, but a symtab from a different objfile.
>
> This problem originates from minsym_found (in linespec.c). The user
> asked for 'break gnu_ifunc' where 'gnu_ifunc' is an ifunc function.
> What this means is that gnu_ifunc is actually a resolver function that
> returns the address of the actual function to use.
>
> In this particular test case, the resolver function is in a shared
> library, and the actual function to use is in the main executable.
>
> So, when GDB looks for 'gnu_ifunc' is finds the minimal_symbol with
> that name, and spots that this has type mst_text_gnu_ifunc. GDB then
> uses this to figure out the actual address of the function that will
> be run.
>
> GDB then creates the symtab_and_line using the _real_ address and the
> symtab in which that address lies, in our case this will all be
> related to the main executable objfile.
>
> But, finally, in minsym_found, GDB fills in the symtab_and_line's
> section field, and this is done using the section containing the
> original minimal_symbol, which is from the shared library objfile.
>
> The minimal symbol and section are then use to initialise the
> bp_location object, and this is how we end up in, what I think, is an
> unexpected state.
>
> So what to do about this?
>
> The symtab_and_line::msymbol field is _only_ set within minsym_found,
> and is then _only_ used to initialise the bp_location::msymbol field.
>
> The bp_location::msymbol field is _only_ used in the function
> set_breakpoint_location_function, and we only really care about the
> msymbol type, we check to see if it's an ifunc symbol or not. This
> allows us to set the name of the function correctly.
>
> The bp_location::section is used, as far as I can tell, extensively
> for overlay handling. It would seem to me, that this section should
> be the section containing the actual breakpoint address. If the
> question we're asking is, is this breakpoint mapped in or not? Then
> surely we need to ask about the section holding the breakpoint's
> address, and not the section holding some other code (e.g. the
> resolver function). In fact, in a memory constrained environment,
> you'd expect the resolver functions to get mapped out pretty early on,
> but while the actual functions might still be mapped in.
>
> Finally, symtab_and_line::section. This is mostly set using calls to
> find_pc_overlay. The minsym_found function is one of the few places
> where we do things differently. In the places where the section is
> used, it is (almost?) always used in conjunction with the
> symtab_and_line::pc to lookup information, e.g. calls to
> block_for_pc_sect, or find_pc_sect_containing_function. In all these
> cases, it appears to me that the assumption is that the section will
> be the section that contains the address.
>
> So, where does this leave us?
>
> I think what we need to do is update minsym_found to just use
> find_pc_overlay, which is how the symtab_and_line::section is set in
> most other cases. What this actually means in practise is that the
> section field will be set to NULL (see find_pc_overlay in symfile.c).
> But given that this is how the section is computed in most other
> cases, I don't see why it should be especially problematic for this
> case. In reality, I think this just means that the section is
> calculated via a call to find_pc_section when it's needed, as an
> example, see lookup_minimal_symbol_by_pc_section (minsyms.c).
>
> I do wonder if we should be doing better when creating the
> symtab_and_line, and insist that the section be calculated correctly
> at that point, but I really don't want to open that can of worms right
> now, so I think just changing minsym_found to "do it just like
> everyone else" should be good enough.
>
> I've extended the existing ifunc test to expose this issue, the
> updated test fails without this patch, and passes with.
The explanation makes sense to me, and I confirm that the test fails
without the fix. So I guess:
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Simon
next prev parent reply other threads:[~2025-09-05 3:11 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-04 20:16 Andrew Burgess
2025-09-05 3:10 ` Simon Marchi [this message]
2025-09-25 15:16 ` Sébastien Darche
2025-09-25 17:56 ` Andrew Burgess
2025-09-25 21:05 ` Simon Marchi
2025-09-25 21:40 ` Andrew Burgess
2025-09-25 22:30 ` Simon Marchi
2025-10-02 19:40 ` Sébastien Darche
2025-10-06 12:11 ` Andrew Burgess
2026-02-02 8:49 ` Rohr, Stephan
2026-02-02 18:45 ` Simon Marchi
2026-02-04 11:55 ` Andrew Burgess
2026-02-04 12:59 ` Andrew Burgess
2026-02-04 16:25 ` Rohr, Stephan
2026-02-12 13:10 ` Andrew Burgess
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=c22f2178-85da-47f7-b103-2e54bbeff5ed@simark.ca \
--to=simark@simark.ca \
--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