Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 19 Dec 2020 14:51:36 +0100
From:      Paul Floyd <pjfloyd@wanadoo.fr>
To:        freebsd-hackers@freebsd.org
Subject:   Re: pthread_self() problem in DRD
Message-ID:  <b40521bc-04c7-d302-d635-a92214fa2152@wanadoo.fr>
In-Reply-To: <X93wG%2BZWC5uPZJSR@kib.kiev.ua>
References:  <61236c3a-05b8-7986-e95d-a9369eaf522b@wanadoo.fr> <X93wG%2BZWC5uPZJSR@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help

> 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





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?b40521bc-04c7-d302-d635-a92214fa2152>