Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace pthread_create during linkage

I want to maintain a list of all running threads with some additional information about each thread. In this answer mentioned that it is possible to provide my own version of pthread_create and to link program with it. It is also important that I want to call original pthread_create in the end of my override version of it.

Could someone explain in details how it could be done and/or provide some code example?

like image 578
eupp Avatar asked Jan 17 '16 16:01

eupp


People also ask

Can pthread_create fail?

The pthread_create() function will fail if: [EAGAIN] The system lacked the necessary resources to create another thread, or the system-imposed limit on the total number of threads in a process PTHREAD_THREADS_MAX would be exceeded.

Does pthread_create return?

pthread_create() returns zero when the call completes successfully. Any other return value indicates that an error occurred. When any of the following conditions are detected, pthread_create() fails and returns the corresponding value.

How many threads does pthread_create create?

System default for the thread limit in a process is set by MAXTHREADS in the BPXPRMxx parmlib member. The maximum number of threads is dependent upon the size of the private area below 16M. pthread_create() inspects this address space before creating a new thread. A realistic limit is 200 to 400 threads.

What are different ways to terminate pthread?

The pthread_exit() function terminates the calling thread, making its exit status available to any waiting threads. Normally, a thread terminates by returning from the start routine that was specified in the pthread_create() call which started it.


1 Answers

You can lookup the symbol for the original pthread_create-function by calling:

pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create");

The wrapper would then look like:

#include <dlfcn.h>

int (*pthread_create_orig)(pthread_t *, const pthread_attr_t *, void *(*) (void *), void *);

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start) (void *), void *arg) {
       if (!pthread_create_orig)
           pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create");
       return pthread_create_orig(thread, attr, start, arg);
}

Compile this as a shared library and preload it when starting your executable.

Explanation: Usually, the first argument of dlsym() is a handle to a library opened with dlopen(). The special handle RTLD_NEXT is used to search the next occurrence of that symbol, i.e. the one which would not be linked by default. This is then the symbol in libpthread, not the one in your preloaded library.

like image 126
Ctx Avatar answered Oct 01 '22 04:10

Ctx