devel/gettext-runtime: Fix crash triggered by libgpg-error

Libgpg-error has an initialisation function with
__attribute__((constructor)) that calls a libintl function that
calls pthread_rwlock_wrlock that segfaults if libpthread wasn't
initialised yet.  This can happen because libintl doesn't link to
libpthread to avoid the overhead for non-threaded programs.  To
fix this, add an initialisation function to libintl that triggers
initialisation of libpthread.

RTLD_NOLOAD suggested by kib.

dlopen was fixed to work during initialisation in
https://cgit.FreeBSD.org/src/commit/?id=1005d3d05362

PR:		272472, 272517
This commit is contained in:
Tijl Coosemans 2023-07-17 15:06:02 +02:00
parent 7052842867
commit fb889ca829
3 changed files with 32 additions and 3 deletions

View file

@ -14,13 +14,14 @@ gettext-runtime_ARGS= lib
. endif
. if ${gettext-runtime_ARGS:Mlib}
BUILD_DEPENDS+= gettext-runtime>=0.22_1:devel/gettext-runtime
LIB_DEPENDS+= libintl.so:devel/gettext-runtime
. endif
. if ${gettext-runtime_ARGS:Mbuild}
BUILD_DEPENDS+= gettext:devel/gettext-runtime
BUILD_DEPENDS+= gettext-runtime>=0.22_1:devel/gettext-runtime
. endif
. if ${gettext-runtime_ARGS:Mrun}
RUN_DEPENDS+= gettext:devel/gettext-runtime
RUN_DEPENDS+= gettext-runtime>=0.22_1:devel/gettext-runtime
. endif
.endif

View file

@ -3,7 +3,7 @@
# discretion.
PORTNAME= gettext-runtime
PORTREVISION= 0
PORTREVISION= 1
COMMENT= GNU gettext runtime libraries and programs
WWW= https://www.gnu.org/software/gettext/

View file

@ -0,0 +1,28 @@
--- intl/osdep.c.orig 2019-05-11 11:29:32 UTC
+++ intl/osdep.c
@@ -18,6 +18,25 @@
# include "intl-exports.c"
#elif defined __EMX__ && !defined __KLIBC__
# include "os2compat.c"
+#elif defined __FreeBSD__
+#include <config.h>
+#include <sys/param.h>
+#include <dlfcn.h>
+#include <pthread.h>
+static __attribute__((constructor)) void
+libintl_init (void)
+{
+#if __FreeBSD_version >= 1400094
+ /* We don't link with libpthread in order to avoid the overhead for
+ non-threaded programs. Instead we dlopen it with RTLD_NOLOAD here
+ to ensure it is initialised when present. */
+ (void) dlopen ("libpthread.so", RTLD_LAZY | RTLD_GLOBAL | RTLD_NOLOAD);
+#else
+ /* For older versions this hack also triggers libpthread
+ initialisation. */
+ (void) pthread_self ();
+#endif
+}
#else
/* Avoid AIX compiler warning. */
typedef int dummy;