Comment remplacer pthread_create pendant la liaison

Je veux maintenir une liste de tous les threads en cours d’exécution avec des informations supplémentaires sur chaque thread. Dans cette réponse , il est mentionné qu’il est possible de fournir ma propre version de pthread_create et d’associer un programme à cette dernière. Il est également important que je veuille appeler pthread_create original à la fin de ma version de substitution.

Quelqu’un pourrait-il expliquer en détail comment cela pourrait être fait et / ou donner un exemple de code?

Vous pouvez rechercher le symbole de la fonction pthread_create d’origine en appelant:

 pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create"); 

Le wrapper ressemblerait alors à ceci:

 #include  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); } 

Comstackz-le en tant que bibliothèque partagée et préchargez-le au démarrage de votre exécutable.

Explanation: Généralement, le premier argument de dlsym() est un handle d’une bibliothèque ouverte avec dlopen() . Le handle spécial RTLD_NEXT est utilisé pour rechercher l’occurrence suivante de ce symbole, c’est-à-dire celle qui ne serait pas liée par défaut. Ceci est alors le symbole dans libpthread, pas celui de votre bibliothèque préchargée.

Si vous voulez vraiment remplacer la fonction, vous pouvez comstackr votre propre bibliothèque partagée avec la fonction pthread_create. De l’intérieur, vous pouvez charger et appeler dynamicment la fonction phtread_create d’origine.

Code de bibliothèque pthread.c :

 #include  #include  #include  int (*original_pthread_create)(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) = NULL; void load_original_pthread_create() { void *handle = dlopen("libpthread-2.15.so", RTLD_LAZY); char *err = dlerror(); if (err) { printf("%s\n", err); } original_pthread_create = dlsym(handle, "pthread_create"); err = dlerror(); if (err) { printf("%s\n", err); } } int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) { if (original_pthread_create == NULL) { load_original_pthread_create(); } printf("I am creating thread from my pthread_create\n"); return original_pthread_create(thread, attr, start_routine, arg); } 

Compilation: gcc pthread.c -o libmypthread.so -shared -fpic -ldl

Utilisation: LD_PRELOAD=./libmypthread.so some_program_using_pthread_create

some_program_using_pthread_create devrait fonctionner normalement, mais à chaque appel de la fonction pthread_create, elle devrait afficher une ligne supplémentaire.

Remarque: placez le nom correct de votre bibliothèque pthread dans la fonction dlopen.