summaryrefslogtreecommitdiff
path: root/debuginfod
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2022-04-22 23:36:30 +0200
committerMark Wielaard <mark@klomp.org>2022-04-25 16:09:41 +0200
commit62963dfc4835405a00463f24e79796c622cc2c84 (patch)
tree3788a955b8586e897fd0b11adef618eca20c41a6 /debuginfod
parent72823322be9a8f0143de21ccfb67a89696a9522f (diff)
downloadelfutils-62963dfc4835405a00463f24e79796c622cc2c84.tar.gz
debuginfod, libdwfl: Initialize libcurl and dlopen debuginfod-client lazily
We used to go out of our way to initialize libcurl early before any other thread/code was running. But this meant that we might pay startup cost, which under FIPS is significant, even for code that never uses libdebuginfod or TLS libcurl connections. Although curl_global_init itself isn't thread-safe we can use pthread_once to make sure we don't race against ourselves. This still means we might race against any application code that might use libcurl. But we can assume they will have called curl_global_init before calling dwfl_begin or debuginfod_begin. Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'debuginfod')
-rw-r--r--debuginfod/ChangeLog10
-rw-r--r--debuginfod/Makefile.am4
-rw-r--r--debuginfod/debuginfod-client.c29
3 files changed, 26 insertions, 17 deletions
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index 0f1bca6f..93c8ae11 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,13 @@
+2022-04-22 Mark Wielaard <mark@klomp.org>
+
+ * Makefile.am (libdebuginfod): Add -lpthread.
+ (libdebuginfod_so_LDLIBS): Likewise.
+ * debuginfod-client.c (init_control): New static pthread_once_t.
+ (libcurl_init): New static function.
+ (debuginfod_begin): Use ptrace_once to call libcurl_init.
+ (libdebuginfod_ctor): Removed.
+ (libdebuginfod_dtor): Likewise.
+
2022-04-24 Mark Wielaard <mark@klomp.org>
* debuginfod.cxx (main): Add MHD_USE_ITC to MHD_start_daemon flags.
diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am
index 3adb2755..435cb8a6 100644
--- a/debuginfod/Makefile.am
+++ b/debuginfod/Makefile.am
@@ -47,7 +47,7 @@ libelf = ../libelf/libelf.a -lz
if DUMMY_LIBDEBUGINFOD
libdebuginfod = ./libdebuginfod.a
else
-libdebuginfod = ./libdebuginfod.a $(libcurl_LIBS)
+libdebuginfod = ./libdebuginfod.a -lpthread $(libcurl_LIBS)
endif
else
libasm = ../libasm/libasm.so
@@ -97,7 +97,7 @@ libdebuginfod_so_LIBS = libdebuginfod_pic.a
if DUMMY_LIBDEBUGINFOD
libdebuginfod_so_LDLIBS =
else
-libdebuginfod_so_LDLIBS = $(libcurl_LIBS) $(fts_LIBS)
+libdebuginfod_so_LDLIBS = -lpthread $(libcurl_LIBS) $(fts_LIBS)
endif
$(LIBDEBUGINFOD_SONAME): $(srcdir)/libdebuginfod.map $(libdebuginfod_so_LIBS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index 58ef6442..45a27b5e 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -1,6 +1,6 @@
/* Retrieve ELF / DWARF / source files from the debuginfod.
Copyright (C) 2019-2021 Red Hat, Inc.
- Copyright (C) 2021 Mark J. Wielaard <mark@klomp.org>
+ Copyright (C) 2021, 2022 Mark J. Wielaard <mark@klomp.org>
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -98,6 +98,16 @@ void debuginfod_end (debuginfod_client *c) { }
#include <fts.h>
#endif
+#include <pthread.h>
+
+static pthread_once_t init_control = PTHREAD_ONCE_INIT;
+
+static void
+libcurl_init(void)
+{
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+}
+
struct debuginfod_client
{
/* Progress/interrupt callback function. */
@@ -1475,6 +1485,9 @@ debuginfod_query_server (debuginfod_client *c,
debuginfod_client *
debuginfod_begin (void)
{
+ /* Initialize libcurl lazily, but only once. */
+ pthread_once (&init_control, libcurl_init);
+
debuginfod_client *client;
size_t size = sizeof (struct debuginfod_client);
client = calloc (1, size);
@@ -1608,18 +1621,4 @@ debuginfod_set_verbose_fd(debuginfod_client *client, int fd)
client->verbose_fd = fd;
}
-
-/* NB: these are thread-unsafe. */
-__attribute__((constructor)) attribute_hidden void libdebuginfod_ctor(void)
-{
- curl_global_init(CURL_GLOBAL_DEFAULT);
-}
-
-/* NB: this is very thread-unsafe: it breaks other threads that are still in libcurl */
-__attribute__((destructor)) attribute_hidden void libdebuginfod_dtor(void)
-{
- /* ... so don't do this: */
- /* curl_global_cleanup(); */
-}
-
#endif /* DUMMY_LIBDEBUGINFOD */