From: Paul Floyd Date: Fri, 4 Dec 2020 09:11:55 +0000 (+0100) Subject: Bug 428909 - helgrind: need to intercept duplicate libc definitions for Fedora 33 X-Git-Tag: VALGRIND_3_17_0~102 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d2d54dbcc74244adfc0c80b40862edf2b82f53b9;p=thirdparty%2Fvalgrind.git Bug 428909 - helgrind: need to intercept duplicate libc definitions for Fedora 33 --- diff --git a/NEWS b/NEWS index c9dfd73155..5861058b16 100644 --- a/NEWS +++ b/NEWS @@ -61,6 +61,7 @@ n-i-bz helgrind: If hg_cli__realloc fails, return NULL. 427870 lmw, lswi and related PowerPC insns aren't allowed on ppc64le 427404 PPC ISA 3.1 support is missing, part 6 429692 unhandled ppc64le-linux syscall: 147 (getsid) +428909 helgrind: need to intercept duplicate libc definitions for Fedora 33 Release 3.16.1 (?? June 2020) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c index 585aafe22e..28c0de78bc 100644 --- a/drd/drd_pthread_intercepts.c +++ b/drd/drd_pthread_intercepts.c @@ -151,7 +151,11 @@ static drd_rtld_guard_fn DRD_(rtld_bind_clear) = NULL; * @param[in] arg_decl Argument declaration list enclosed in parentheses. * @param[in] argl Argument list enclosed in parentheses. */ -#ifdef VGO_darwin +#if defined(VGO_darwin) +/* + * Note here VGO_darwin is used rather than VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY + * because of the special-case code adding a function call + */ static int never_true; #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ @@ -164,29 +168,12 @@ static int never_true; fflush(stdout); \ return pth_func_result; \ } -#elif defined(VGO_solaris) -/* On Solaris, libpthread is just a filter library on top of libc. - * Threading and synchronization functions in runtime linker are not - * intercepted. - */ +#elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_ONLY) #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl; \ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl \ { return implf argl; } -#else -#ifdef MUSL_LIBC -/* musl provides a single library that includes pthreads functions. */ -#define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ - { return implf argl; } -#else -/* - * On Linux, intercept both the libc and the libpthread functions. At - * least glibc 2.32.9000 (Fedora 34) has an implementation of all pthread - * functions in both libc and libpthread. Older glibc versions only have an - * implementation of the pthread functions in libpthread. - */ +#elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD) #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl; \ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl \ @@ -194,7 +181,8 @@ static int never_true; ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ { return implf argl; } -#endif +#else +# error "Unknown platform/thread wrapping" #endif /** diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c index a10c3a4a3b..2bc89f8a09 100644 --- a/helgrind/hg_intercepts.c +++ b/helgrind/hg_intercepts.c @@ -78,26 +78,37 @@ /*----------------------------------------------------------------*/ #if defined(VGO_solaris) -/* On Solaris, libpthread is just a filter library on top of libc. - * Threading and synchronization functions in runtime linker are not - * intercepted. - */ -#define PTH_FUNC(ret_ty, f, args...) \ - ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args); \ - ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args) - /* pthread_t is typedef'd to 'unsigned int' but in DO_CREQ_* macros sizeof(Word) is expected. */ #define CREQ_PTHREAD_T Word #define SEM_ERROR ret #else -#define PTH_FUNC(ret_ty, f, args...) \ - ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args); \ - ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args) #define CREQ_PTHREAD_T pthread_t #define SEM_ERROR errno #endif /* VGO_solaris */ +#define HG_EXPAND(tok) #tok +#define HG_STR(tok) HG_EXPAND(tok) +#define HG_WEAK_ALIAS(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((weak, alias(HG_STR(name)))) + +#if defined(VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY) +#define PTH_FUNC(ret_ty, f, args...) \ + ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args); \ + ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args) +#elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD) +#define PTH_FUNC(ret_ty, f, args...) \ + ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args); \ + HG_WEAK_ALIAS(I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f), I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)); \ + ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args) +#elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_ONLY) +#define PTH_FUNC(ret_ty, f, args...) \ + ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args); \ + ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args) +#else +# error "Unknown platform/thread wrapping" +#endif + // Do a client request. These are macros rather than a functions so // as to avoid having an extra frame in stack traces. diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h index bd65a44b45..7c7a76b7dd 100644 --- a/include/pub_tool_redir.h +++ b/include/pub_tool_redir.h @@ -277,11 +277,7 @@ /* --- Soname of the pthreads library. --- */ #if defined(VGO_linux) -# if defined(MUSL_LIBC) -# define VG_Z_LIBPTHREAD_SONAME libcZdZa // libc.* -#else # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd0 // libpthread.so.0 -#endif #elif defined(VGO_darwin) # define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib #elif defined(VGO_solaris) @@ -364,6 +360,42 @@ Bool VG_(is_soname_ld_so) (const HChar *soname); +// Some macros to help decide which libraries (libc or libpthread +// or some platform-specific variation of these) should be used +// for wrapping pthread/semaphore functions with DRD and Helgrind +// The possibilities are +// a) only in libpthread +// b) mabye in both libpthread and libc or +// c) only in libc + +// Linux GNU libc is moving from a) to c) +// Fedora 33 has pthread functions in both libc and libpthread +// and at least glibc 2.32 (Fedora 34) has an implementation of all pthread +// functions in both libc and libpthread. Older glibc versions only have an +// implementation of the pthread functions in libpthread. + +// Linux MUSL libc is c) it provides a single library that includes +// pthreads functions. + +// Darwin is a) + +// Solaris is c) libpthread is just a filter library on top of libc. +// Threading and synchronization functions in runtime linker are not +// intercepted. + +// FreeBSD is b) pthread functions are lin libthr but semaphore +// functions are lin libc + +#if defined(VGO_darwin) +#define VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY +#elif defined(VGO_solaris) || (defined(VGO_linux) && defined(MUSL_LIBC)) +#define VG_WRAP_THREAD_FUNCTION_LIBC_ONLY +#elif defined(VGO_linux) +#define VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD +#else +# error "Unknown platform" +#endif + #endif // __PUB_TOOL_REDIR_H /*--------------------------------------------------------------------*/