From: Andrew Burgess <aburgess@redhat.com>
To: Luis Machado <luis.machado@arm.com>, gdb-patches@sourceware.org
Cc: thiago.bauermann@linaro.org
Subject: Re: [PATCH v7 15/18] [gdb/generic] corefile/bug: Add hook to control the use of target description notes from corefiles
Date: Thu, 21 Sep 2023 11:02:56 +0100 [thread overview]
Message-ID: <87il83yhbj.fsf@redhat.com> (raw)
In-Reply-To: <423fed06-ce80-52d0-013d-03384fecc853@arm.com>
Luis Machado <luis.machado@arm.com> writes:
> On 9/20/23 16:26, Andrew Burgess wrote:
>> Andrew Burgess <aburgess@redhat.com> writes:
>>
>>> Luis Machado via Gdb-patches <gdb-patches@sourceware.org> writes:
>>>
>>>> New entry in v7.
>>>>
>>>> ---
>>>>
>>>> Due to the nature of the AArch64 SVE/SME extensions in GDB, each thread
>>>> can potentially have distinct target descriptions/gdbarches.
>>>>
>>>> When loading a gcore-generated core file, at the moment GDB gives priority
>>>> to the target description dumped to NT_GDB_TDESC. Though technically correct
>>>> for most targets, it doesn't work correctly for AArch64 with SVE or SME
>>>> support.
>>>>
>>>> The correct approach for AArch64/Linux is to either have per-thread target
>>>> description notes in the corefiles or to rely on the
>>>> gdbarch_core_read_description hook, so it can figure out the proper target
>>>> description for a given thread based on the various available register notes.
>>>>
>>>> The former, although more correct, doesn't address the case of existing gdb's
>>>> that only output a single target description note.
>>>
>>> Do those existing GDB's support per-thread target descriptions though?
>>> I thought this series was the where the per-thread target description
>>> feature was being added ... so shouldn't core files generated by
>>> previous GDB's only support a single target description? Or am I
>>> missing something.
>>>
>>>>
>>>> This patch goes for the latter, and adds a new gdbarch hook to conditionalize
>>>> the use of the corefile target description note. The hook is called
>>>> use_target_description_from_corefile_notes.
>>>>
>>>> The hook defaults to returning true, meaning targets will use the corefile
>>>> target description note. AArch64 Linux overrides the hook to return false
>>>> when it detects any of the SVE or SME register notes in the corefile.
>>>>
>>>> Otherwise it should be fine for AArch64 Linux to use the corefile target
>>>> description note.
>>>>
>>>> When we support per-thread target description notes, then we can augment
>>>> the AArch64 Linux hook to rely on those notes.
>>>
>>> I guess I was a little surprised that I couldn't see anywhere in this
>>> series that you _stop_ adding the NT_GDB_TDESC note to core files
>>> generated from within GDB.
>>>
>>> I guess I was expecting to see some logic in gcore_elf_make_tdesc_note
>>> that tried to figure out if we had per-thread tdesc, and if so, at a
>>> minimum, didn't add the NT_GDB_TDESC.
>>>
>>> If we did that, then, I'm thinking:
>>>
>>> - Previous GDB's only supported a single tdesc, and so are correct,
>>>
>>> - New GDB's support per-thread tdesc, but don't emit NT_GDB_TDESC, so
>>> we don't need to guard against loading them
>>>
>>> Maybe I'm missing something though.
>>
>> Luis,
>>
>> After our discussion on IRC I think I understand this a bit more, so
>> thanks for that.
>
> You're welcome. Hopefully I managed to clarify most of it.
>
>>
>> So, here's what I think is true:
>>
>> - AArch64 supports per-thread gdbarch since before this patch series
>> (implements ::thread_architecture),
>>
>> - GDB by default writes out a single NT_GDB_TDESC which describes the
>> "per-inferior" gdbarch, but this doesn't correctly represent the
>> per-thread gdbarch/tdesc,
>>
>> - If a NT_GDB_TDESC is present then GDB is going to try and load it
>> back in and use it,
>>
>> - This is a problem that has existed for a while, but you've only just
>> become aware, and so you're fixing it here,
>>
>> - The new gdbarch hook allows an architecture to avoid loading a
>> single NT_GDB_TDESC note, for AArch64 this is when we see registers
>> that are (likely) going to require per-thread gdbarch/tdesc,
>>
>
> All of the above are correct.
>
>> I'm hoping we both agree on the above. So from there I think I has two
>> concerns:
>>
>> 1. GDB should avoid writing out the NT_GDB_TDESC is the situation where
>> it know that a single such note is not correct, and
>
> I see your point now. Not outputting NT_GDB_TDESC when it is incorrect sounds
> reasonable, even if the incorrect NT_GDB_TDESC note won't be used.
>
> It is also reasonable to do it until the point where we support per-thread
> NT_GDB_TDESC's, which is, I think, the proper solution.
>
>>
>> 2. I wonder if there's a better solution than the new hook.
>>
>> For point (1) the patch below is a rough draft of what I'm thinking
>> about: by looking at each of the gdbarch pointers we can spot if an
>> inferior uses multiple different gdbarches -- if it does then we know
>> that a single NT_GDB_TDESC is going to be wrong, so lets not write it
>> out.
>>
>> As was mentioned on IRC, longer term, it might be better if we wrote out
>> one tdesc for each thread, but that feels like a bigger job, and I think
>> stopping GDB doing something that's just *wrong* is pretty easy, so why
>> wouldn't we do that?
>
> I think outputting per-thread NT_GDB_TDESC's is fairly easy. Probably a matter of
> calling the function that outputs NT_GDB_TDESC while we're dumping register sets for
> each thread.
Indeed, I have this bit done locally. What isn't clear to me is how
having multiple NT_GDB_TDESC will help -- does
core_file::read_description get called multiple times when using AArch64
with sve/sme?
>
> I haven't investigated in-depth how to use that information when loading a core file, but
> there might be some complexity because we read the target description before we load the threads.
>
> If the target description we read first is *always* the one for the signalled thread, then we might
> be ok and it should make the implementation easier. Anyway, that's a
> bit off-topic for this patch.
I mean, maybe this is a better solution? What if
gcore_elf_make_tdesc_note took a 'struct gdbarch *' argument, and it was
the callers to chose which gdbarch to pass. We would then spec in the
comments of gcore_elf_make_tdesc_note that the passed in gdbarch should
be the gdbarch of the signalled thread. See the patch below.
Could I ask: would you mind sending me a small application and corefile
for AArch64 with sve/sme please. I'd love to have a play to better
understand how GDB sets up the per-thread gdbarch in that case. I'd be
very grateful.
>
>>
>> For point (2) I agree with the premise that we need a mechanism to stop
>> AArch64 loading the incorrect single NT_GDB_TDESC. This is a slight
>> change in stance from what I originally wrote, but our IRC conversation
>> showed me I was wrong originally. I don't have time this evening to
>> look at this, but will follow up again tomorrow with more thoughts.
I wonder, instead of adding the new hook, maybe we should just reorder
the checks in core_target::read_description -- ask the gdbarch to grok a
tdesc from the .regs (etc) sections, and if that fails, check for an
encoded tdesc.
When I originally added this code my problem case was RISC-V, where the
CSRs (control regs) for embedded targets can be different for each
target. The CSRs are just encoded as a blob, so unless you already know
which regs are present you're stuck. For real h/w the controller
(e.g. openocd) provides a tdesc (via target.xml), but for a core file we
needed a way to reacquire the tdesc.
My assumption at the time that the tdesc we wrote would always be
correct, but clearly this isn't the case.
Right now RISC-V doesn't event override gdbarch_core_read_description,
so if we read the encoded tdesc after checking that gdbarch hook nothing
would change.
For other architectures, if gdbarch_core_read_description is implemented
then we'll be back to using that, and that worked fine before.
... And if, in some future world we do implement
gdbarch_core_read_description for RISC-V then the solution seems
obvious, if there's a section containing CSRs, and there's also a
section containing a tdesc, then the RISC-V
gdbarch_core_read_description can just return nullptr, safe in the
knowledge the generic GDB code will load the encoded tdesc.
>
> Except for some different names and tweaks, your proposed approach works correctly.
>
> I tested this and noticed the lack of NT_GDB_TDESC for a AArch64 Linux target
> with sve/sme support and one thread with a differing gdbarch. I also saw the note for
> a AArch64 Linux target without sve/sme support, or with sve/sme support but all threads
> having the exact same gdbarch. So that looks good to me.
>
> Would you like this extra code to be included as part of this
> particular patch?
Yeah I think something like this should be added to this patch, we
should stop GDB creating incorrect core files I think.
Thanks,
Andrew
----
diff --git a/gdb/elf-none-tdep.c b/gdb/elf-none-tdep.c
index 460f02e7dbb..ad31d3c820a 100644
--- a/gdb/elf-none-tdep.c
+++ b/gdb/elf-none-tdep.c
@@ -111,7 +111,9 @@ elf_none_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
/* Target description. */
- gcore_elf_make_tdesc_note (obfd, ¬e_data, note_size);
+ if (signalled_thr != nullptr)
+ gdbarch = target_thread_architecture (signalled_thr->ptid);
+ gcore_elf_make_tdesc_note (gdbarch, obfd, ¬e_data, note_size);
return note_data;
}
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index dc5020d92d2..c44dc0871c6 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -774,7 +774,9 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
}
/* Include the target description when possible. */
- gcore_elf_make_tdesc_note (obfd, ¬e_data, note_size);
+ if (signalled_thr != nullptr)
+ gdbarch = target_thread_architecture (signalled_thr->ptid);
+ gcore_elf_make_tdesc_note (gdbarch, obfd, ¬e_data, note_size);
return note_data;
}
diff --git a/gdb/gcore-elf.c b/gdb/gcore-elf.c
index 643426d911b..0142db82670 100644
--- a/gdb/gcore-elf.c
+++ b/gdb/gcore-elf.c
@@ -139,12 +139,12 @@ gcore_elf_build_thread_register_notes
/* See gcore-elf.h. */
void
-gcore_elf_make_tdesc_note (bfd *obfd,
+gcore_elf_make_tdesc_note (struct gdbarch *gdbarch, bfd *obfd,
gdb::unique_xmalloc_ptr<char> *note_data,
int *note_size)
{
/* Append the target description to the core file. */
- const struct target_desc *tdesc = gdbarch_target_desc (target_gdbarch ());
+ const struct target_desc *tdesc = gdbarch_target_desc (gdbarch);
const char *tdesc_xml
= tdesc == nullptr ? nullptr : tdesc_get_features_xml (tdesc);
if (tdesc_xml != nullptr && *tdesc_xml != '\0')
diff --git a/gdb/gcore-elf.h b/gdb/gcore-elf.h
index 2cfeb3e8550..e23fe5e7162 100644
--- a/gdb/gcore-elf.h
+++ b/gdb/gcore-elf.h
@@ -42,6 +42,7 @@ extern void gcore_elf_build_thread_register_notes
set to nullptr. */
extern void gcore_elf_make_tdesc_note
- (bfd *obfd, gdb::unique_xmalloc_ptr<char> *note_data, int *note_size);
+ (struct gdbarch *gdbarch, bfd *obfd,
+ gdb::unique_xmalloc_ptr<char> *note_data, int *note_size);
#endif /* GCORE_ELF_H */
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 2885afd60c7..24ae1d711d1 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -1836,6 +1836,10 @@ linux_corefile_thread (struct thread_info *info,
such a core file is useless. */
if (note_data != nullptr)
{
+ /* If we want per-thread NT_GDB_TDESC then at this point we should
+ do this: */
+ // gcore_elf_make_tdesc_note (gdbarch, obfd, ¬e_data, note_size);
+
gdb::byte_vector siginfo_data
= linux_get_siginfo_data (info, gdbarch);
if (!siginfo_data.empty ())
@@ -2125,7 +2129,9 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
linux_make_mappings_corefile_notes (gdbarch, obfd, note_data, note_size);
/* Target description. */
- gcore_elf_make_tdesc_note (obfd, ¬e_data, note_size);
+ if (signalled_thr != nullptr)
+ gdbarch = target_thread_architecture (signalled_thr->ptid);
+ gcore_elf_make_tdesc_note (gdbarch, obfd, ¬e_data, note_size);
return note_data;
}
---
next prev parent reply other threads:[~2023-09-21 10:03 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-18 21:26 [PATCH v7 00/18] SME support for AArch64 gdb/gdbserver on Linux Luis Machado
2023-09-18 21:26 ` [PATCH v7 01/18] [gdb/aarch64] Fix register fetch/store order for native AArch64 Linux Luis Machado
2023-09-18 21:26 ` [PATCH v7 02/18] [gdb/aarch64] refactor: Rename SVE-specific files Luis Machado
2023-09-18 21:26 ` [PATCH v7 03/18] [gdb/gdbserver] refactor: Simplify SVE interface to read/write registers Luis Machado
2023-09-18 21:26 ` [PATCH v7 04/18] [gdb/aarch64] sve: Fix return command when using V registers in a SVE-enabled target Luis Machado
2023-09-18 21:26 ` [PATCH v7 05/18] [gdb/aarch64] sme: Enable SME registers and pseudo-registers Luis Machado
2023-10-13 13:06 ` Tom Tromey
2023-10-13 14:44 ` Luis Machado
2023-10-13 14:50 ` Luis Machado
2023-09-18 21:26 ` [PATCH v7 06/18] [gdbserver/generic] Convert tdesc's expedite_regs to a string vector Luis Machado
2023-09-18 21:26 ` [PATCH v7 07/18] [gdbserver/aarch64] refactor: Adjust expedited registers dynamically Luis Machado
2023-09-18 21:26 ` [PATCH v7 08/18] [gdbserver/aarch64] sme: Add support for SME Luis Machado
2023-09-18 21:26 ` [PATCH v7 09/18] [gdb/aarch64] sve: Fix signal frame z/v register restore Luis Machado
2023-09-18 21:26 ` [PATCH v7 10/18] [gdb/aarch64] sme: Signal frame support Luis Machado
2023-09-18 21:26 ` [PATCH v7 11/18] [gdb/aarch64] sme: Fixup sigframe gdbarch when vg/svg changes Luis Machado
2023-09-18 21:26 ` [PATCH v7 12/18] [gdb/aarch64] sme: Support TPIDR2 signal frame context Luis Machado
2023-09-18 21:26 ` [PATCH v7 13/18] [gdb/generic] Get rid of linux-core-thread-data Luis Machado
2023-09-18 21:26 ` [PATCH v7 14/18] [gdb/generic] corefile/bug: Use thread-specific gdbarch when dumping register state to core files Luis Machado
2023-09-18 21:26 ` [PATCH v7 15/18] [gdb/generic] corefile/bug: Add hook to control the use of target description notes from corefiles Luis Machado
2023-09-19 20:49 ` Simon Marchi
2023-09-20 5:49 ` Luis Machado
2023-09-20 14:01 ` Luis Machado
2023-09-20 14:22 ` Andrew Burgess
2023-09-20 15:26 ` Andrew Burgess
2023-09-20 23:35 ` Luis Machado
2023-09-21 10:02 ` Andrew Burgess [this message]
2023-09-21 10:44 ` Luis Machado
2023-09-25 9:57 ` Andrew Burgess
2023-09-26 12:39 ` Luis Machado
2023-09-27 17:56 ` Andrew Burgess
2023-09-28 8:23 ` Luis Machado
2023-10-03 17:23 ` Andrew Burgess
2023-10-04 15:27 ` Luis Machado
2023-09-25 15:41 ` Simon Marchi
2023-09-27 17:44 ` Andrew Burgess
2023-09-18 21:26 ` [PATCH v7 16/18] [gdb/aarch64] sme: Core file support for Linux Luis Machado
2023-09-18 21:26 ` [PATCH v7 17/18] [gdb/testsuite] sme: Add SVE/SME testcases Luis Machado
2023-09-19 19:12 ` Simon Marchi
2023-09-19 20:02 ` Luis Machado
2023-09-18 21:26 ` [PATCH v7 18/18] [gdb/docs] sme: Document SME registers and features Luis Machado
2023-10-04 15:27 ` [PATCH v7 00/18] SME support for AArch64 gdb/gdbserver on Linux 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=87il83yhbj.fsf@redhat.com \
--to=aburgess@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=luis.machado@arm.com \
--cc=thiago.bauermann@linaro.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).