pthread_self() problem in DRD
Paul Floyd
pjfloyd at wanadoo.fr
Sat Dec 19 13:51:40 UTC 2020
> It is impossible to say anything definitive without minimal self-contained
> example, but it is possible to make some guess.
Here is the source
/* dlopen_main.c */
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include "dlopen_lib.h"
int main(int argc, char **argv)
{
const char *lib = argc > 1 ? argv[1] : "./libfoo.so";
void *handle;
void (*function)();
const char *error;
handle = dlopen(lib, RTLD_NOW);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
function = dlsym(handle, "foo");
error = dlerror();
if (error) {
fputs(error, stderr);
exit(1);
}
(*function)();
dlclose(handle);
return 0;
}
/* dlopen_lib.c */
#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#include "dlopen_lib.h"
void *PrintHello(void *threadid)
{
const long tid = (uintptr_t)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
void foo()
{
pthread_t thread;
int rc;
uintptr_t t = 1;
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&thread, NULL, PrintHello, (void *)t);
if (rc)
printf("ERROR; return code from pthread_create() is %d\n", rc);
else
pthread_join(thread, NULL);
}
Command to execute:
valgrind -tool=drd -q ./dlopen_main ./dlopen_lib.so
> In FreeBSD, libc exports pthread stubs which main purpose is to satisfy
> linkage requirements of the shared objects that can work in multithreaded
> environment but do not require it. For instance, pthread_self() is exported
> from libc, and it returns a pointer to some internal non-sensical memory
> when called, until libthr is loaded and initialized. At the moment libthr
> is initialized, pthread_self() starts returning 'real' pthread_t.
>
> In your case, my guess is that one of two things happen:
> 1. you have first pthread_self() call from the process that does not have
> libthr loaded, then later dlopen(3) loads dso which is linked with libhtr.
> Second call to pthread_self() returns real pthread_t for main thread.
> 2. (less likely but possible to arrange) You process has libthr linked in,
> but your first call to pthread_self() from constructor occurs before
> constructors for libthr are run. Visible outcome is same.
That sounds quite plausible. The valgrind tools do not link with any
libraries themselves.
I'll see what effect doing a dlopen of libthr.so in the DRD init
function has.
A+
Paul
More information about the freebsd-hackers
mailing list