All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ian Rogers <irogers@google.com>
Cc: Guilherme Amadio <amadio@gentoo.org>,
	Namhyung Kim <namhyung@kernel.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>,
	Adrian Hunter <adrian.hunter@intel.com>,
	linux-perf-users@vger.kernel.org, Ingo Molnar <mingo@redhat.com>,
	linux-kernel@vger.kernel.org,
	Peter Zijlstra <peterz@infradead.org>
Subject: Re: [PATCH v2] perf libbfd: Ensure libbfd is initialized prior to use
Date: Thu, 13 Nov 2025 17:42:25 -0300	[thread overview]
Message-ID: <aRZCsU8x0ebgxT6R@x1> (raw)
In-Reply-To: <CAP-5=fU6xad0EGzQ=gJy6eUJtYrgV2FKSu=JcndeWVTKZE_RrA@mail.gmail.com>

On Thu, Nov 13, 2025 at 09:03:42AM -0800, Ian Rogers wrote:
> On Tue, Nov 11, 2025 at 11:43 PM Ian Rogers <irogers@google.com> wrote:
> >
> > Multiple threads may be creating and destroying BFD objects in
> > situations like `perf top`. Without appropriate initialization crashes
> > may occur during libbfd's cache management. BFD's locks require
> > recursive mutexes, add support for these.
> >
> > Reported-by: Guilherme Amadio <amadio@gentoo.org>
> > Closes: https://lore.kernel.org/lkml/aQt66zhfxSA80xwt@gentoo.org/
> > Fixes: 95931d9a594d ("perf libbfd: Move libbfd functionality to its own file")
> > Signed-off-by: Ian Rogers <irogers@google.com>
> 
> I'm hoping adding the missing initialization is just obviously
> correct, Guilherme if you could provide a Tested-by it would be great.

I reproduced the problem by building with BUILD_NONDISTRO=1 + having
binutils-devel installed, 'perf top' segfaults straight away.

After applying this patch things gets back to normal.

Thanks, applied.

- Arnaldo
 
> Thanks,
> Ian
> 
> > ---
> > v2: Remove unneeded unistd.h include.
> > ---
> >  tools/perf/util/libbfd.c | 38 ++++++++++++++++++++++++++++++++++++++
> >  tools/perf/util/mutex.c  | 14 ++++++++++----
> >  tools/perf/util/mutex.h  |  2 ++
> >  3 files changed, 50 insertions(+), 4 deletions(-)
> >
> > diff --git a/tools/perf/util/libbfd.c b/tools/perf/util/libbfd.c
> > index 01147fbf73b3..6434c2dccd4a 100644
> > --- a/tools/perf/util/libbfd.c
> > +++ b/tools/perf/util/libbfd.c
> > @@ -38,6 +38,39 @@ struct a2l_data {
> >         asymbol **syms;
> >  };
> >
> > +static bool perf_bfd_lock(void *bfd_mutex)
> > +{
> > +       mutex_lock(bfd_mutex);
> > +       return true;
> > +}
> > +
> > +static bool perf_bfd_unlock(void *bfd_mutex)
> > +{
> > +       mutex_unlock(bfd_mutex);
> > +       return true;
> > +}
> > +
> > +static void perf_bfd_init(void)
> > +{
> > +       static struct mutex bfd_mutex;
> > +
> > +       mutex_init_recursive(&bfd_mutex);
> > +
> > +       if (bfd_init() != BFD_INIT_MAGIC) {
> > +               pr_err("Error initializing libbfd\n");
> > +               return;
> > +       }
> > +       if (!bfd_thread_init(perf_bfd_lock, perf_bfd_unlock, &bfd_mutex))
> > +               pr_err("Error initializing libbfd threading\n");
> > +}
> > +
> > +static void ensure_bfd_init(void)
> > +{
> > +       static pthread_once_t bfd_init_once = PTHREAD_ONCE_INIT;
> > +
> > +       pthread_once(&bfd_init_once, perf_bfd_init);
> > +}
> > +
> >  static int bfd_error(const char *string)
> >  {
> >         const char *errmsg;
> > @@ -132,6 +165,7 @@ static struct a2l_data *addr2line_init(const char *path)
> >         bfd *abfd;
> >         struct a2l_data *a2l = NULL;
> >
> > +       ensure_bfd_init();
> >         abfd = bfd_openr(path, NULL);
> >         if (abfd == NULL)
> >                 return NULL;
> > @@ -288,6 +322,7 @@ int dso__load_bfd_symbols(struct dso *dso, const char *debugfile)
> >         bfd *abfd;
> >         u64 start, len;
> >
> > +       ensure_bfd_init();
> >         abfd = bfd_openr(debugfile, NULL);
> >         if (!abfd)
> >                 return -1;
> > @@ -393,6 +428,7 @@ int libbfd__read_build_id(const char *filename, struct build_id *bid, bool block
> >         if (fd < 0)
> >                 return -1;
> >
> > +       ensure_bfd_init();
> >         abfd = bfd_fdopenr(filename, /*target=*/NULL, fd);
> >         if (!abfd)
> >                 return -1;
> > @@ -421,6 +457,7 @@ int libbfd_filename__read_debuglink(const char *filename, char *debuglink,
> >         asection *section;
> >         bfd *abfd;
> >
> > +       ensure_bfd_init();
> >         abfd = bfd_openr(filename, NULL);
> >         if (!abfd)
> >                 return -1;
> > @@ -480,6 +517,7 @@ int symbol__disassemble_bpf_libbfd(struct symbol *sym __maybe_unused,
> >         memset(tpath, 0, sizeof(tpath));
> >         perf_exe(tpath, sizeof(tpath));
> >
> > +       ensure_bfd_init();
> >         bfdf = bfd_openr(tpath, NULL);
> >         if (bfdf == NULL)
> >                 abort();
> > diff --git a/tools/perf/util/mutex.c b/tools/perf/util/mutex.c
> > index bca7f0717f35..7aa1f3f55a7d 100644
> > --- a/tools/perf/util/mutex.c
> > +++ b/tools/perf/util/mutex.c
> > @@ -17,7 +17,7 @@ static void check_err(const char *fn, int err)
> >
> >  #define CHECK_ERR(err) check_err(__func__, err)
> >
> > -static void __mutex_init(struct mutex *mtx, bool pshared)
> > +static void __mutex_init(struct mutex *mtx, bool pshared, bool recursive)
> >  {
> >         pthread_mutexattr_t attr;
> >
> > @@ -27,21 +27,27 @@ static void __mutex_init(struct mutex *mtx, bool pshared)
> >         /* In normal builds enable error checking, such as recursive usage. */
> >         CHECK_ERR(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK));
> >  #endif
> > +       if (recursive)
> > +               CHECK_ERR(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE));
> >         if (pshared)
> >                 CHECK_ERR(pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED));
> > -
> >         CHECK_ERR(pthread_mutex_init(&mtx->lock, &attr));
> >         CHECK_ERR(pthread_mutexattr_destroy(&attr));
> >  }
> >
> >  void mutex_init(struct mutex *mtx)
> >  {
> > -       __mutex_init(mtx, /*pshared=*/false);
> > +       __mutex_init(mtx, /*pshared=*/false, /*recursive=*/false);
> >  }
> >
> >  void mutex_init_pshared(struct mutex *mtx)
> >  {
> > -       __mutex_init(mtx, /*pshared=*/true);
> > +       __mutex_init(mtx, /*pshared=*/true, /*recursive=*/false);
> > +}
> > +
> > +void mutex_init_recursive(struct mutex *mtx)
> > +{
> > +       __mutex_init(mtx, /*pshared=*/false, /*recursive=*/true);
> >  }
> >
> >  void mutex_destroy(struct mutex *mtx)
> > diff --git a/tools/perf/util/mutex.h b/tools/perf/util/mutex.h
> > index 38458f00846f..70232d8d094f 100644
> > --- a/tools/perf/util/mutex.h
> > +++ b/tools/perf/util/mutex.h
> > @@ -104,6 +104,8 @@ void mutex_init(struct mutex *mtx);
> >   * process-private attribute.
> >   */
> >  void mutex_init_pshared(struct mutex *mtx);
> > +/* Initializes a mutex that may be recursively held on the same thread. */
> > +void mutex_init_recursive(struct mutex *mtx);
> >  void mutex_destroy(struct mutex *mtx);
> >
> >  void mutex_lock(struct mutex *mtx) EXCLUSIVE_LOCK_FUNCTION(*mtx);
> > --
> > 2.51.2.1041.gc1ab5b90ca-goog
> >

      parent reply	other threads:[~2025-11-13 20:42 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-12  7:43 [PATCH v2] perf libbfd: Ensure libbfd is initialized prior to use Ian Rogers
2025-11-13 17:03 ` Ian Rogers
2025-11-13 20:25   ` Guilherme Amadio
2025-11-13 20:42     ` Ian Rogers
2025-11-13 20:31   ` Arnaldo Carvalho de Melo
2025-11-13 20:42   ` Arnaldo Carvalho de Melo [this message]

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=aRZCsU8x0ebgxT6R@x1 \
    --to=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=amadio@gentoo.org \
    --cc=irogers@google.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.