- --- /dev/null 2022-07-25 11:42:10.933510077 +0200
- +++ pthread_interceptor/Makefile 2022-08-01 15:09:58.790413283 +0200
- @@ -0,0 +1,53 @@
- +#
- +# Makefile for LD_PRELOAD pthreadinterceptor
- +#
- +
- +#
- +# ToDo:
- +# - cleanup (this Makefile is horrible and should actually use macros)
- +# - build 32bit and 64bit at the same time
- +#
- +
- +CSTDFLAGS=-std=c17
- +CARCHFLAGS=-m32 # -m32 or -m64
- +CC=gcc # gcc or clang
- +
- +#
- +# misc
- +#
- +all: run_test pthr_inter_binaries.tar.bz2
- +
- +clean:
- + rm -f *.o *.so test1 pthr_inter_binaries.tar.bz2
- +
- +#
- +# build LD_PRELOAD function interceptor
- +#
- +pthread_interceptor.o: pthread_interceptor.c
- + $(CC) $(CSTDFLAGS) $(CARCHFLAGS) -Wall -g pthread_interceptor.c -fPIC -rdynamic -c -o pthread_interceptor.o
- +pthread_interceptor.so: pthread_interceptor.o
- + $(CC) $(CSTDFLAGS) $(CARCHFLAGS) -Wall -g pthread_interceptor.o -fPIC -rdynamic -shared -ldl -lpthread -o pthread_interceptor.so
- +
- +#
- +# tests
- +#
- +
- +# -rdynamic is required so that we get accurate function names
- +# from |backtrace()|&co
- +test1: test1.c
- + $(CC) $(CSTDFLAGS) $(CARCHFLAGS) -Wall -rdynamic -g test1.c -o test1
- +
- +run_test: test1 pthread_interceptor.so pthread_interceptor_wrapper.ksh
- + @printf "# Begin tests.\n"
- + ksh93 pthread_interceptor_wrapper.ksh ./test1
- + @printf "# End tests.\n"
- +
- +#
- +# package binaries
- +#
- +pthr_inter_binaries.tar.bz2: pthread_interceptor.so pthread_interceptor_wrapper.ksh
- + tar -cvf - pthread_interceptor.so pthread_interceptor_wrapper.ksh | \
- + bzip2 -9 >"pthr_inter_binaries.tar.bz2"
- +
- +
- +# EOF.
- --- /dev/null 2022-07-25 11:42:10.933510077 +0200
- +++ pthread_interceptor/pthread_interceptor.c 2022-08-01 15:29:50.137635263 +0200
- @@ -0,0 +1,118 @@
- +/*
- + * pthread_interceptor.c
- + *
- + * intercept pthread calls
- + * (like |pthread_mutex_init()|) via LD_PRELOAD
- + *
- + * Example usage:
- + * $ ksh93 -c 'LD_PRELOAD="$PWD/pthread_interceptor.so" ./test_prog'
- + *
- + * Written by Roland Mainz <roland.mainz@nrubsig.org>
- + */
- +
- +#define _GNU_SOURCE 1 /* needed for |RTLD_NEXT| */
- +
- +#include <pthread.h>
- +#include <unistd.h>
- +#include <errno.h>
- +#include <stdio.h>
- +#include <string.h>
- +#include <stdbool.h>
- +#include <dlfcn.h>
- +#include <execinfo.h>
- +
- +/* config */
- +#define PICFG_PRINT_ONCE_MSG 1
- +#define PICFG_ENFORCE_PRIO_INHERIT 1
- +#define PICFG_PRINT_BACKTRACE 1
- +
- +/* misc */
- +#define STDERR_MSG(msg) \
- + (void)write(STDERR_FILENO, (msg), strlen(msg))
- +
- +
- +#if PICFG_PRINT_ONCE_MSG
- +static pthread_once_t picfg_init_once = PTHREAD_ONCE_INIT;
- +
- +static
- +void picfg_init(void)
- +{
- + const char *mymessage = "# pthread_interceptor.so: "
- + "Once: In our own pthread_mutex_init()\n";
- + STDERR_MSG(mymessage);
- +}
- +#endif /* PICFG_PRINT_ONCE_MSG */
- +
- +
- +
- +/*
- + * interceptor for |pthread_mutex_init()|
- + */
- +int pthread_mutex_init(pthread_mutex_t *restrict mutex,
- + const pthread_mutexattr_t *restrict attr) {
- + pthread_mutexattr_t *xattr = (pthread_mutexattr_t *)attr;
- + int pmi_res;
- + int pmi_errno;
- +
- +#if PICFG_PRINT_ONCE_MSG
- + (void)pthread_once(&picfg_init_once, picfg_init);
- +#endif /* PICFG_PRINT_ONCE_MSG */
- +
- + int (*original_pthread_mutex_init)(pthread_mutex_t *restrict mutex,
- + const pthread_mutexattr_t *restrict attr);
- + original_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init");
- +
- + pthread_mutexattr_t myattr;
- + bool myattr_used = false;
- +
- + if (!xattr) {
- + (void)pthread_mutexattr_init(&myattr);
- + myattr_used = true;
- + xattr = &myattr;
- + }
- +
- +#if PICFG_ENFORCE_PRIO_INHERIT
- + int mutex_protocol = -666;
- + (void)pthread_mutexattr_getprotocol(xattr, &mutex_protocol);
- + if (mutex_protocol != PTHREAD_PRIO_INHERIT) {
- + char msgbuff[256]; /* fixed size, but no |malloc()| allowed here */
- +
- + (void)pthread_mutexattr_setprotocol(xattr, PTHREAD_PRIO_INHERIT);
- + (void)snprintf(msgbuff,
- + sizeof(msgbuff),
- + "# pthread_interceptor.so: "
- + "PTHREAD_PRIO_INHERIT enforced "
- + "for mutex=0x%lx, was protocol=%d\n",
- + (unsigned long)(void *)mutex,
- + mutex_protocol);
- + STDERR_MSG(msgbuff);
- +
- +#if PICFG_PRINT_BACKTRACE
- +#define BT_BUFF_ELEMENTS 256
- +#define MYMIN(a,b) (((a) < (b)) ? (a) : (b))
- + /*
- + * print backtrace
- + * Might cause a gross mix of marmelade if multiple
- + * threads write at the same time, and syslog is used
- + * to log stderr
- + * To limit the madness we restrict the backtrace to
- + * four lines
- + */
- + void *bt_buffer[BT_BUFF_ELEMENTS];
- + int nptrs;
- + nptrs = backtrace(bt_buffer, BT_BUFF_ELEMENTS);
- + backtrace_symbols_fd(bt_buffer, MYMIN(nptrs,4), STDERR_FILENO);
- + }
- +#endif /* PICFG_PRINT_BACKTRACE */
- +#endif /* PICFG_ENFORCE_PRIO_INHERIT */
- +
- + pmi_res = (*original_pthread_mutex_init)(mutex, xattr);
- + pmi_errno = errno;
- +
- + if (myattr_used) {
- + (void)pthread_mutexattr_destroy(&myattr);
- + }
- +
- + errno = pmi_errno;
- + return pmi_res;
- +}
- --- /dev/null 2022-07-25 11:42:10.933510077 +0200
- +++ pthread_interceptor/pthread_interceptor_wrapper.ksh 2022-08-01 11:48:14.603478675 +0200
- @@ -0,0 +1,12 @@
- +#!/bin/ksh93
- +
- +#
- +# pthread_interceptor wrapper script
- +#
- +
- +export LD_PRELOAD="$PWD/pthread_interceptor.so:$LD_PRELOAD"
- +
- +"$@"
- +
- +# EOF.
- +
- --- /dev/null 2022-07-25 11:42:10.933510077 +0200
- +++ pthread_interceptor/test1.c 2022-08-01 14:54:55.634801754 +0200
- @@ -0,0 +1,30 @@
- +/*
- + * test1 for pthread_interceptor.c
- + *
- + */
- +
- +#include <stdlib.h>
- +#include <stdio.h>
- +#include <pthread.h>
- +#include <errno.h>
- +
- +void run_tests1(void)
- +{
- + pthread_mutex_t mutex1;
- + pthread_mutex_t mutex2;
- +
- + (void)pthread_mutex_init(&mutex1, NULL);
- + perror("pthread_mutex_init(mutex1) result");
- +
- + (void)pthread_mutex_init(&mutex2, NULL);
- + perror("pthread_mutex_init(mutex2) result");
- +}
- +
- +int main(int ac, char *av[])
- +{
- + (void)puts("# start.");
- + run_tests1();
- + (void)puts("# end.");
- +
- + return EXIT_SUCCESS;
- +}
Intercepting pthread_mutext_init() via LD_PRELOAD
Posted by Anonymous on Mon 1st Aug 2022 16:32
raw | new post
view followups (newest first): Intercepting pthread_mutext_init() via LD_PRELOAD by Anonymous
modification of post by Anonymous (view diff)
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.