mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-30 15:21:04 +01:00
BUG/MEDIUM: tools: avoid calling dlsym() in static builds (try 2)
The first approach in commit 288dc1d8e ("BUG/MEDIUM: tools: avoid calling
dlsym() in static builds") relied on dlopen() but on certain configs (at
least gcc-4.8+ld-2.27+glibc-2.17) it used to catch situations where it
ought not fail.
Let's have a second try on this using dladdr() instead. The variable was
renamed "build_is_static" as it's exactly what's being detected there.
We could even take it for reporting in -vv though that doesn't seem very
useful. At least the variable was made global to ease inspection via the
debugger, or in case it's useful later.
Now it properly detects a static build even with gcc-4.4+glibc-2.11.1 and
doesn't crash anymore.
This commit is contained in:
parent
bc50e0d0fb
commit
5b3cd9561b
@ -70,6 +70,7 @@ extern int strlcpy2(char *dst, const char *src, int size);
|
|||||||
*/
|
*/
|
||||||
extern THREAD_LOCAL int itoa_idx; /* index of next itoa_str to use */
|
extern THREAD_LOCAL int itoa_idx; /* index of next itoa_str to use */
|
||||||
extern THREAD_LOCAL char itoa_str[][171];
|
extern THREAD_LOCAL char itoa_str[][171];
|
||||||
|
extern int build_is_static;
|
||||||
extern char *ultoa_r(unsigned long n, char *buffer, int size);
|
extern char *ultoa_r(unsigned long n, char *buffer, int size);
|
||||||
extern char *lltoa_r(long long int n, char *buffer, int size);
|
extern char *lltoa_r(long long int n, char *buffer, int size);
|
||||||
extern char *sltoa_r(long n, char *buffer, int size);
|
extern char *sltoa_r(long n, char *buffer, int size);
|
||||||
|
|||||||
34
src/tools.c
34
src/tools.c
@ -98,6 +98,9 @@ THREAD_LOCAL int quoted_idx = 0;
|
|||||||
*/
|
*/
|
||||||
THREAD_LOCAL unsigned int statistical_prng_state = 2463534242U;
|
THREAD_LOCAL unsigned int statistical_prng_state = 2463534242U;
|
||||||
|
|
||||||
|
/* set to true if this is a static build */
|
||||||
|
int build_is_static = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* unsigned long long ASCII representation
|
* unsigned long long ASCII representation
|
||||||
*
|
*
|
||||||
@ -4920,22 +4923,25 @@ static int dladdr_and_size(const void *addr, Dl_info *dli, size_t *size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dlopen() support: 0=no/not yet checked, 1=ok */
|
/* Sets build_is_static to true if we detect a static build. Some older glibcs
|
||||||
static int dlopen_usable = 0;
|
* tend to crash inside dlsym() in static builds, but tests show that at least
|
||||||
|
* dladdr() still works (and will fail to resolve anything of course). Thus we
|
||||||
/* Sets dlopen_usable to true if dlopen() works and is usable. We verify if
|
* try to determine if we're on a static build to avoid calling dlsym() in this
|
||||||
* we're in a static build because some old glibcs used to crash in dlsym()
|
* case.
|
||||||
* in this case.
|
|
||||||
*/
|
*/
|
||||||
void check_if_dlopen_usable()
|
void check_if_static_build()
|
||||||
{
|
{
|
||||||
/* dlopen(NULL) returns a handle to the main program or NULL
|
Dl_info dli = { };
|
||||||
* on static builds.
|
size_t size = 0;
|
||||||
*/
|
|
||||||
dlopen_usable = dlopen(NULL, RTLD_LAZY) ? 1 : 0;
|
/* Now let's try to be smarter */
|
||||||
|
if (!dladdr_and_size(&main, &dli, &size))
|
||||||
|
build_is_static = 1;
|
||||||
|
else
|
||||||
|
build_is_static = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
INITCALL0(STG_PREPARE, check_if_dlopen_usable);
|
INITCALL0(STG_PREPARE, check_if_static_build);
|
||||||
|
|
||||||
/* Tries to retrieve the address of the first occurrence symbol <name>.
|
/* Tries to retrieve the address of the first occurrence symbol <name>.
|
||||||
* Note that NULL in return is not always an error as a symbol may have that
|
* Note that NULL in return is not always an error as a symbol may have that
|
||||||
@ -4946,7 +4952,7 @@ void *get_sym_curr_addr(const char *name)
|
|||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
|
|
||||||
#ifdef RTLD_DEFAULT
|
#ifdef RTLD_DEFAULT
|
||||||
if (dlopen_usable)
|
if (!build_is_static)
|
||||||
ptr = dlsym(RTLD_DEFAULT, name);
|
ptr = dlsym(RTLD_DEFAULT, name);
|
||||||
#endif
|
#endif
|
||||||
return ptr;
|
return ptr;
|
||||||
@ -4962,7 +4968,7 @@ void *get_sym_next_addr(const char *name)
|
|||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
|
|
||||||
#ifdef RTLD_NEXT
|
#ifdef RTLD_NEXT
|
||||||
if (dlopen_usable)
|
if (!build_is_static)
|
||||||
ptr = dlsym(RTLD_NEXT, name);
|
ptr = dlsym(RTLD_NEXT, name);
|
||||||
#endif
|
#endif
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user