summaryrefslogtreecommitdiffstats
path: root/libdwfl
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 /libdwfl
parentAUTHORS: Use generator script & git mailmap (diff)
downloadelfutils-62963dfc4835405a00463f24e79796c622cc2c84.tar.gz
elfutils-62963dfc4835405a00463f24e79796c622cc2c84.tar.bz2
elfutils-62963dfc4835405a00463f24e79796c622cc2c84.tar.xz
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 'libdwfl')
-rw-r--r--libdwfl/ChangeLog7
-rw-r--r--libdwfl/debuginfod-client.c14
2 files changed, 18 insertions, 3 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 9c5c8517..76053039 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
12022-04-22 Mark Wielaard <mark@klomp.org>
2
3 * debuginfod-client.c (init_control): New static pthread_once_t.
4 (get_client): Use pthread_once to call __libdwfl_debuginfod_init.
5 (__libdwfl_debuginfod_init): Make static, remove attribute
6 constructor.
7
12022-02-18 Mark Wielaard <mark@klomp.org> 82022-02-18 Mark Wielaard <mark@klomp.org>
2 9
3 * image-header.c (__libdw_image_header): Assign header values for 10 * image-header.c (__libdw_image_header): Assign header values for
diff --git a/libdwfl/debuginfod-client.c b/libdwfl/debuginfod-client.c
index 99b66b6e..153260c3 100644
--- a/libdwfl/debuginfod-client.c
+++ b/libdwfl/debuginfod-client.c
@@ -1,5 +1,6 @@
1/* Try to get an ELF or debug file through the debuginfod. 1/* Try to get an ELF or debug file through the debuginfod.
2 Copyright (C) 2019 Red Hat, Inc. 2 Copyright (C) 2019 Red Hat, Inc.
3 Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
3 This file is part of elfutils. 4 This file is part of elfutils.
4 5
5 This file is free software; you can redistribute it and/or modify 6 This file is free software; you can redistribute it and/or modify
@@ -31,6 +32,7 @@
31#endif 32#endif
32 33
33#include "libdwflP.h" 34#include "libdwflP.h"
35#include <pthread.h>
34#include <dlfcn.h> 36#include <dlfcn.h>
35 37
36static __typeof__ (debuginfod_begin) *fp_debuginfod_begin; 38static __typeof__ (debuginfod_begin) *fp_debuginfod_begin;
@@ -38,6 +40,10 @@ static __typeof__ (debuginfod_find_executable) *fp_debuginfod_find_executable;
38static __typeof__ (debuginfod_find_debuginfo) *fp_debuginfod_find_debuginfo; 40static __typeof__ (debuginfod_find_debuginfo) *fp_debuginfod_find_debuginfo;
39static __typeof__ (debuginfod_end) *fp_debuginfod_end; 41static __typeof__ (debuginfod_end) *fp_debuginfod_end;
40 42
43static void __libdwfl_debuginfod_init (void);
44
45static pthread_once_t init_control = PTHREAD_ONCE_INIT;
46
41/* NB: this is slightly thread-unsafe */ 47/* NB: this is slightly thread-unsafe */
42 48
43static debuginfod_client * 49static debuginfod_client *
@@ -46,6 +52,8 @@ get_client (Dwfl *dwfl)
46 if (dwfl->debuginfod != NULL) 52 if (dwfl->debuginfod != NULL)
47 return dwfl->debuginfod; 53 return dwfl->debuginfod;
48 54
55 pthread_once (&init_control, __libdwfl_debuginfod_init);
56
49 if (fp_debuginfod_begin != NULL) 57 if (fp_debuginfod_begin != NULL)
50 { 58 {
51 dwfl->debuginfod = (*fp_debuginfod_begin) (); 59 dwfl->debuginfod = (*fp_debuginfod_begin) ();
@@ -96,9 +104,9 @@ __libdwfl_debuginfod_end (debuginfod_client *c)
96 (*fp_debuginfod_end) (c); 104 (*fp_debuginfod_end) (c);
97} 105}
98 106
99/* Try to get the libdebuginfod library functions to make sure 107/* Try to get the libdebuginfod library functions.
100 everything is initialized early. */ 108 Only needs to be called once from get_client. */
101void __attribute__ ((constructor)) 109static void
102__libdwfl_debuginfod_init (void) 110__libdwfl_debuginfod_init (void)
103{ 111{
104 void *debuginfod_so = dlopen(DEBUGINFOD_SONAME, RTLD_LAZY); 112 void *debuginfod_so = dlopen(DEBUGINFOD_SONAME, RTLD_LAZY);