From: Luis Machado <luis.machado@arm.com>
To: Andrew Burgess <aburgess@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH] gdb/aarch64: prevent crash from in process agent
Date: Thu, 13 Jun 2024 11:04:45 +0100 [thread overview]
Message-ID: <56322fd8-9cf8-457c-8891-be0f5e41f5eb@arm.com> (raw)
In-Reply-To: <f18d8f32e1e8af423e38efd0cb58ced1a98b5efb.1718271737.git.aburgess@redhat.com>
On 6/13/24 10:42, Andrew Burgess wrote:
> Since this commit:
>
> commit 0ee6b1c511c0e2a6793568692d2e5418cd6bc10d
> Date: Wed May 18 13:32:04 2022 -0700
>
> Use aarch64_features to describe register features in target descriptions.
>
> There has been an issue with how aarch64 target descriptions are
> cached within gdbserver, and specifically, how this caching impacts
> the in process agent (IPA).
>
> The function initialize_tracepoint_ftlib (gdbserver/tracepoint.cc) is
> part of the IPA, this function is a constructor function, i.e. is
> called as part of the global initialisation process. We can't
> guarantee the ordering of when this function is called vs when other
> global state is initialised.
>
> Now initialize_tracepoint_ftlib calls initialize_tracepoint, which
> calls initialize_low_tracepoint, which for aarch64 calls
> aarch64_linux_read_description.
>
> The aarch64_linux_read_description function lives in
> linux-aarch64-tdesc.cc and after the above commit, depends on a
> std::unordered_map having been initialized.
>
> Prior to the above commit aarch64_linux_read_description used a global
> C style array, which obviously requires no runtime initialization.
>
> The consequence of the above is that any inferior linked with the IPA
> (for aarch64) will experience undefined behaviour (access to an
> uninitialized std::unordered_map) during startup, which for me
> manifests as a segfault.
>
> I propose fixing this by moving the std::unordered_map into the
> function body, but leaving it static. The map will now be initialized
> the first time the function is called, which removes the undefiend
> behaviour.
>
> The same problem exists for the expedited_registers global, however
> this global can just be made into a function local instead. The
> expedited_registers variable is used to build a pointer list which is
> then passed to init_target_desc, however init_target_desc copies the
> values it is given so expedited_registers does not need to live longer
> than its containing function.
>
> On most of the AArch64 machines I have access too tracing is not
> supported, and so the gdb.trace/*.exp tests that use the IPA just exit
> early reporting unsupported. I've added a test which links an
> inferior with the IPA and just starts the inferior. No tracing is
> performed. This exposes the current issue even on hosts that don't
> support tracing. After this patch the test passes.
> ---
> gdb/testsuite/gdb.trace/basic-libipa.c | 22 ++++++++++++
> gdb/testsuite/gdb.trace/basic-libipa.exp | 45 ++++++++++++++++++++++++
> gdbserver/linux-aarch64-tdesc.cc | 22 +++++++-----
> 3 files changed, 81 insertions(+), 8 deletions(-)
> create mode 100644 gdb/testsuite/gdb.trace/basic-libipa.c
> create mode 100644 gdb/testsuite/gdb.trace/basic-libipa.exp
>
> diff --git a/gdb/testsuite/gdb.trace/basic-libipa.c b/gdb/testsuite/gdb.trace/basic-libipa.c
> new file mode 100644
> index 00000000000..bbcfb01316e
> --- /dev/null
> +++ b/gdb/testsuite/gdb.trace/basic-libipa.c
> @@ -0,0 +1,22 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2024 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/>. */
> +
> +int
> +main ()
> +{
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.trace/basic-libipa.exp b/gdb/testsuite/gdb.trace/basic-libipa.exp
> new file mode 100644
> index 00000000000..c457d6afc36
> --- /dev/null
> +++ b/gdb/testsuite/gdb.trace/basic-libipa.exp
> @@ -0,0 +1,45 @@
> +# Copyright 2024 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/>.
> +
> +# Very simple test that links with libinproctrace.so and then starts
> +# the resulting inferior.
> +#
> +# This test should run on targets that don't support tracing, but for
> +# which libinproctrace.so is built and helps catch some issues where
> +# libinproctrace.so is so broken inferiors wont even start.
> +
> +load_lib "trace-support.exp"
> +
> +require allow_shlib_tests
> +
> +standard_testfile
> +
> +set libipa [get_in_proc_agent]
> +gdb_download_shlib $libipa
> +
> +if { ![file exists $libipa] } {
> + unsupported "missing libinproctrace.so"
> + return -1
> +}
> +
> +if { [prepare_for_testing "failed to prepare" $testfile $srcfile \
> + [list debug shlib=$libipa]] } {
> + return -1
> +}
> +
> +if {![runto_main]} {
> + return -1
> +}
> +
> +pass "inferior with libinproctrace.so started"
> diff --git a/gdbserver/linux-aarch64-tdesc.cc b/gdbserver/linux-aarch64-tdesc.cc
> index 0ed9a42cbff..5d3b6ddffff 100644
> --- a/gdbserver/linux-aarch64-tdesc.cc
> +++ b/gdbserver/linux-aarch64-tdesc.cc
> @@ -26,16 +26,17 @@
> #include <inttypes.h>
> #include <unordered_map>
>
> -/* All possible aarch64 target descriptors. */
> -static std::unordered_map<aarch64_features, target_desc *> tdesc_aarch64_map;
> -
> -static std::vector<const char *> expedited_registers;
> -
> /* Create the aarch64 target description. */
>
> const target_desc *
> aarch64_linux_read_description (const aarch64_features &features)
> {
> + /* All possible aarch64 target descriptors. This map must live within
> + this function as the in-process-agent calls this function from a
> + constructor function, when globals might not yet have been
> + initialised. */
> + static std::unordered_map<aarch64_features, target_desc *> tdesc_aarch64_map;
> +
> if (features.vq > AARCH64_MAX_SVE_VQ)
> error (_("VQ is %" PRIu64 ", maximum supported value is %d"), features.vq,
> AARCH64_MAX_SVE_VQ);
> @@ -50,10 +51,15 @@ aarch64_linux_read_description (const aarch64_features &features)
> if (tdesc == NULL)
> {
> tdesc = aarch64_create_target_description (features);
> - expedited_registers.clear ();
>
> - /* Configure the expedited registers. By default we include x29, sp and
> - pc. */
> + /* Configure the expedited registers. By default we include x29, sp
> + and pc, but we allow for up to 6 pointers as this is (currently)
> + the most that we push.
> +
> + Calling init_target_desc takes a copy of all the strings pointed
> + to by expedited_registers so this vector only needs to live for
> + the scope of this function. */
> + std::vector<const char *> expedited_registers (6);
> expedited_registers.push_back ("x29");
> expedited_registers.push_back ("sp");
> expedited_registers.push_back ("pc");
>
> base-commit: 6dfd07222c02edc792447049ba94518ae982f362
Thanks. This is OK. Though, as I mentioned in previous threads touching
tracepoints/IPA, I think we should just rip out the IPA. Nobody seems
to be using it, and it is just a maintenance burden at this point.
Approved-By: Luis Machado <luis.machado@arm.com>
next prev parent reply other threads:[~2024-06-13 10:05 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-13 9:42 Andrew Burgess
2024-06-13 10:04 ` Luis Machado [this message]
2024-06-14 13:48 ` 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=56322fd8-9cf8-457c-8891-be0f5e41f5eb@arm.com \
--to=luis.machado@arm.com \
--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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).