pastebin - collaborative debugging tool
rovema.kpaste.net RSS


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)

  1. --- /dev/null   2022-07-25 11:42:10.933510077 +0200
  2. +++ pthread_interceptor/Makefile        2022-08-01 15:09:58.790413283 +0200
  3. @@ -0,0 +1,53 @@
  4. +#
  5. +# Makefile for LD_PRELOAD pthreadinterceptor
  6. +#
  7. +
  8. +#
  9. +# ToDo:
  10. +# - cleanup (this Makefile is horrible and should actually use macros)
  11. +# - build 32bit and 64bit at the same time
  12. +#
  13. +
  14. +CSTDFLAGS=-std=c17
  15. +CARCHFLAGS=-m32 # -m32 or -m64
  16. +CC=gcc # gcc or clang
  17. +
  18. +#
  19. +# misc
  20. +#
  21. +all:   run_test pthr_inter_binaries.tar.bz2
  22. +
  23. +clean:
  24. +       rm -f *.o *.so test1 pthr_inter_binaries.tar.bz2
  25. +
  26. +#
  27. +# build LD_PRELOAD function interceptor
  28. +#
  29. +pthread_interceptor.o: pthread_interceptor.c
  30. +       $(CC) $(CSTDFLAGS) $(CARCHFLAGS) -Wall -g pthread_interceptor.c -fPIC -rdynamic -c -o pthread_interceptor.o
  31. +pthread_interceptor.so: pthread_interceptor.o
  32. +       $(CC) $(CSTDFLAGS) $(CARCHFLAGS) -Wall -g pthread_interceptor.o -fPIC -rdynamic -shared -ldl -lpthread -o pthread_interceptor.so
  33. +
  34. +#
  35. +# tests
  36. +#
  37. +
  38. +# -rdynamic is required so that we get accurate function names
  39. +# from |backtrace()|&co
  40. +test1: test1.c
  41. +       $(CC) $(CSTDFLAGS) $(CARCHFLAGS) -Wall -rdynamic -g test1.c -o test1
  42. +      
  43. +run_test: test1 pthread_interceptor.so pthread_interceptor_wrapper.ksh
  44. +       @printf "# Begin tests.\n"
  45. +       ksh93 pthread_interceptor_wrapper.ksh ./test1
  46. +       @printf "# End tests.\n"
  47. +
  48. +#
  49. +# package binaries
  50. +#
  51. +pthr_inter_binaries.tar.bz2: pthread_interceptor.so pthread_interceptor_wrapper.ksh
  52. +       tar -cvf - pthread_interceptor.so pthread_interceptor_wrapper.ksh | \
  53. +               bzip2 -9 >"pthr_inter_binaries.tar.bz2"
  54. +
  55. +
  56. +# EOF.
  57. --- /dev/null   2022-07-25 11:42:10.933510077 +0200
  58. +++ pthread_interceptor/pthread_interceptor.c   2022-08-01 15:29:50.137635263 +0200
  59. @@ -0,0 +1,118 @@
  60. +/*
  61. + * pthread_interceptor.c
  62. + *
  63. + * intercept pthread calls
  64. + * (like |pthread_mutex_init()|) via LD_PRELOAD
  65. + *
  66. + * Example usage:
  67. + * $ ksh93 -c 'LD_PRELOAD="$PWD/pthread_interceptor.so" ./test_prog'
  68. + *
  69. + * Written by Roland Mainz <roland.mainz@nrubsig.org>
  70. + */
  71. +
  72. +#define _GNU_SOURCE 1 /* needed for |RTLD_NEXT| */
  73. +
  74. +#include <pthread.h>
  75. +#include <unistd.h>
  76. +#include <errno.h>
  77. +#include <stdio.h>
  78. +#include <string.h>
  79. +#include <stdbool.h>
  80. +#include <dlfcn.h>
  81. +#include <execinfo.h>
  82. +
  83. +/* config */
  84. +#define PICFG_PRINT_ONCE_MSG           1
  85. +#define PICFG_ENFORCE_PRIO_INHERIT     1
  86. +#define PICFG_PRINT_BACKTRACE          1
  87. +
  88. +/* misc */
  89. +#define STDERR_MSG(msg) \
  90. +       (void)write(STDERR_FILENO, (msg), strlen(msg))
  91. +
  92. +
  93. +#if PICFG_PRINT_ONCE_MSG
  94. +static pthread_once_t picfg_init_once = PTHREAD_ONCE_INIT;
  95. +
  96. +static
  97. +void picfg_init(void)
  98. +{
  99. +       const char *mymessage = "# pthread_interceptor.so: "
  100. +               "Once: In our own pthread_mutex_init()\n";
  101. +       STDERR_MSG(mymessage);
  102. +}
  103. +#endif /* PICFG_PRINT_ONCE_MSG */
  104. +
  105. +
  106. +
  107. +/*
  108. + * interceptor for |pthread_mutex_init()|
  109. + */
  110. +int pthread_mutex_init(pthread_mutex_t *restrict mutex,
  111. +               const pthread_mutexattr_t *restrict attr) {
  112. +       pthread_mutexattr_t *xattr = (pthread_mutexattr_t *)attr;
  113. +       int pmi_res;
  114. +       int pmi_errno;
  115. +
  116. +#if PICFG_PRINT_ONCE_MSG
  117. +       (void)pthread_once(&picfg_init_once, picfg_init);
  118. +#endif /* PICFG_PRINT_ONCE_MSG */
  119. +
  120. +       int (*original_pthread_mutex_init)(pthread_mutex_t *restrict mutex,
  121. +               const pthread_mutexattr_t *restrict attr);
  122. +       original_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init");
  123. +
  124. +       pthread_mutexattr_t myattr;
  125. +       bool myattr_used = false;
  126. +
  127. +       if (!xattr) {
  128. +               (void)pthread_mutexattr_init(&myattr);
  129. +               myattr_used = true;
  130. +               xattr = &myattr;
  131. +       }
  132. +
  133. +#if PICFG_ENFORCE_PRIO_INHERIT
  134. +       int mutex_protocol = -666;
  135. +       (void)pthread_mutexattr_getprotocol(xattr, &mutex_protocol);
  136. +       if (mutex_protocol != PTHREAD_PRIO_INHERIT) {
  137. +               char msgbuff[256]; /* fixed size, but no |malloc()| allowed here */
  138. +      
  139. +               (void)pthread_mutexattr_setprotocol(xattr, PTHREAD_PRIO_INHERIT);
  140. +               (void)snprintf(msgbuff,
  141. +                       sizeof(msgbuff),
  142. +                       "# pthread_interceptor.so: "
  143. +                       "PTHREAD_PRIO_INHERIT enforced "
  144. +                       "for mutex=0x%lx, was protocol=%d\n",
  145. +                       (unsigned long)(void *)mutex,
  146. +                       mutex_protocol);
  147. +               STDERR_MSG(msgbuff);
  148. +
  149. +#if PICFG_PRINT_BACKTRACE
  150. +#define BT_BUFF_ELEMENTS 256
  151. +#define MYMIN(a,b) (((a) < (b)) ? (a) : (b))
  152. +               /*
  153. +                * print backtrace
  154. +                * Might cause a gross mix of marmelade if multiple
  155. +                * threads write at the same time, and syslog is used
  156. +                * to log stderr
  157. +                * To limit the madness we restrict the backtrace to
  158. +                * four lines
  159. +                */
  160. +               void *bt_buffer[BT_BUFF_ELEMENTS];
  161. +               int nptrs;
  162. +               nptrs = backtrace(bt_buffer, BT_BUFF_ELEMENTS);
  163. +               backtrace_symbols_fd(bt_buffer, MYMIN(nptrs,4), STDERR_FILENO);
  164. +       }
  165. +#endif /* PICFG_PRINT_BACKTRACE */
  166. +#endif /* PICFG_ENFORCE_PRIO_INHERIT */
  167. +
  168. +       pmi_res = (*original_pthread_mutex_init)(mutex, xattr);
  169. +       pmi_errno = errno;
  170. +
  171. +       if (myattr_used) {
  172. +               (void)pthread_mutexattr_destroy(&myattr);
  173. +       }
  174. +
  175. +       errno = pmi_errno;
  176. +       return pmi_res;
  177. +}
  178. --- /dev/null   2022-07-25 11:42:10.933510077 +0200
  179. +++ pthread_interceptor/pthread_interceptor_wrapper.ksh 2022-08-01 11:48:14.603478675 +0200
  180. @@ -0,0 +1,12 @@
  181. +#!/bin/ksh93
  182. +
  183. +#
  184. +# pthread_interceptor wrapper script
  185. +#
  186. +
  187. +export LD_PRELOAD="$PWD/pthread_interceptor.so:$LD_PRELOAD"
  188. +
  189. +"$@"
  190. +
  191. +# EOF.
  192. +
  193. --- /dev/null   2022-07-25 11:42:10.933510077 +0200
  194. +++ pthread_interceptor/test1.c 2022-08-01 14:54:55.634801754 +0200
  195. @@ -0,0 +1,30 @@
  196. +/*
  197. + * test1 for pthread_interceptor.c
  198. + *
  199. + */
  200. +
  201. +#include <stdlib.h>
  202. +#include <stdio.h>
  203. +#include <pthread.h>
  204. +#include <errno.h>
  205. +
  206. +void run_tests1(void)
  207. +{
  208. +       pthread_mutex_t mutex1;
  209. +       pthread_mutex_t mutex2;
  210. +      
  211. +       (void)pthread_mutex_init(&mutex1, NULL);
  212. +       perror("pthread_mutex_init(mutex1) result");
  213. +
  214. +       (void)pthread_mutex_init(&mutex2, NULL);
  215. +       perror("pthread_mutex_init(mutex2) result");
  216. +}
  217. +
  218. +int main(int ac, char *av[])
  219. +{
  220. +       (void)puts("# start.");
  221. +       run_tests1();
  222. +       (void)puts("# end.");
  223. +
  224. +       return EXIT_SUCCESS;
  225. +}

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at