pthread_self() problem in DRD

Paul Floyd pjfloyd at
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] : "./";
   void *handle;
   void (*function)();
   const char *error;

   handle = dlopen(lib, RTLD_NOW);
   if (!handle) {
     fputs (dlerror(), stderr);

   function = dlsym(handle, "foo");
   error = dlerror();
   if (error)  {
     fputs(error, stderr);

   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);

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);
     pthread_join(thread, NULL);

Command to execute:

valgrind -tool=drd -q ./dlopen_main ./

> 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 in the DRD init 
function has.



More information about the freebsd-hackers mailing list