Re: weak symbols

2015-04-08 Thread Ted Unangst
Martijn van Duren wrote:
> Could you inform me on the preferred way for making a library thread safe?
> - always linking in lpthread into the library (which causes some extra 
> bloat in the loading of the extra library).
> - making the required symbols available via weak symbols, as per my 
> original question. (which might not be very portable and might make the 
> code less transparent)
> - making custom functions which load in the required symbols via dlsym 
> (which requires extra LoC)
> - another method I haven't thought of?

The second option is probably the best approach today. There are some annoying
downsides to linking directly against libpthread, since it then requires every
application to do the same. Using dlsym doesn't seem much much better than
using weak symbols.



Re: weak symbols

2015-04-08 Thread Martijn van Duren

On 04/08/15 08:10, Philip Guenther wrote:

On Tue, 7 Apr 2015, Martijn van Duren wrote:

I'm currently experimenting with weak symbols for a library that I want
to be thread safe without hard linking in the entire libpthread.

To test this I've set up the following code:

...

When compiling with pthread it seems it only resolves
pthread_mutex_init, but still uses the weak pthread_create and executes
secondary lock first:

...

Could someone please elaborate on what I'm doing wrong and how to implement
these weak symbols properly. Thank you in advance.


If the symbol is defined in the base executable, then it cannot be
overriden by a shared library, regardless of its binding (global or weak)
in the executable.  Indeed, the reference will be resolved when the
executable is created, leaving no relocation dependent on the symbol
definition.

If you want to work with symbol interposition like this, you'll need to
actually build shared libraries.


Philip Guenther



Thank you, this seems to work.

I've also been looking at other ways to make this work, like by making a 
custom cpthread_* function, which in turns loads pthread_create via 
dlsym(RTLD_NEXT, "pthread_create") and test the output for NULL, which 
also seems to work.


Could you inform me on the preferred way for making a library thread safe?
- always linking in lpthread into the library (which causes some extra 
bloat in the loading of the extra library).
- making the required symbols available via weak symbols, as per my 
original question. (which might not be very portable and might make the 
code less transparent)
- making custom functions which load in the required symbols via dlsym 
(which requires extra LoC)

- another method I haven't thought of?

To make my question even more concrete: I intend to lock a file with 
flock, which isn't thread safe. Is there a (portable) way to lock a file 
for both processes and threads alike, or should I construct a wrapper 
with extra locking as per my question mentioned above?


Martijn van Duren



Re: weak symbols

2015-04-07 Thread Philip Guenther
On Tue, 7 Apr 2015, Martijn van Duren wrote:
> I'm currently experimenting with weak symbols for a library that I want 
> to be thread safe without hard linking in the entire libpthread.
> 
> To test this I've set up the following code:
...
> When compiling with pthread it seems it only resolves 
> pthread_mutex_init, but still uses the weak pthread_create and executes 
> secondary lock first:
...
> Could someone please elaborate on what I'm doing wrong and how to implement
> these weak symbols properly. Thank you in advance.

If the symbol is defined in the base executable, then it cannot be 
overriden by a shared library, regardless of its binding (global or weak) 
in the executable.  Indeed, the reference will be resolved when the 
executable is created, leaving no relocation dependent on the symbol 
definition.

If you want to work with symbol interposition like this, you'll need to 
actually build shared libraries.


Philip Guenther



weak symbols

2015-04-07 Thread Martijn van Duren

Hello misc@,

I'm currently experimenting with weak symbols for a library that I want 
to be thread safe without hard linking in the entire libpthread.


To test this I've set up the following code:
#include 
#include 
#include 
#include 
#include 

pthread_mutex_t mut;

#pragma weak pthread_create
#pragma weak pthread_mutex_init
#pragma weak pthread_mutex_lock
#pragma weak pthread_mutex_unlock

int
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void 
*(*start_routine)(void *), void *arg) {

start_routine(arg);
return 0;
}

int
pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t 
*attr) {

return 0;
}

int
pthread_mutex_lock(pthread_mutex_t *mutex) {
return 0;
}

int
pthread_mutex_unlock(pthread_mutex_t *mutex) {
return 0;
}

void *
thread(void *arg) {
sleep(1);

pthread_mutex_lock(&mut);
printf("Got secondary lock\n");

sleep(2);

pthread_mutex_unlock(&mut);
printf("Released secondary lock\n");

return NULL;
}

int
main()
{
pthread_t   tid;

pthread_mutex_init(&mut, NULL);
pthread_create(&tid, NULL, &thread, NULL);

pthread_mutex_lock(&mut);
printf("Got main lock\n");

sleep(2);
pthread_mutex_unlock(&mut);
printf("Released main lock\n");
sleep(2);
}

When compiling without pthread it runs as expected:
$ gcc ./test.c 




$ ./a.out 




Got secondary lock
Released secondary lock
Got main lock
Released main lock
$ nm -e ./a.out 




002011f0 a   _DYNAMIC
00301338 a   _GLOBAL_OFFSET_TABLE_
 W   _Jv_RegisterClasses
004013d8 A   __bss_start
 W   __cxa_atexit -> _dl_searchnum
00201018 D   __dso_handle
0f30 T   __fini
00301338 D   __got_start
00201008 D   __guard_local
0ad0 T   __init
 W   __init_tcb
00201010 D   __progname
00401440 B   __progname_storage
0c90 W   __register_frame_info -> (null)
 U   __stack_smash_handler
0b60 T   __start
00401420 B   _dl_skipnum
004013d8 A   _edata
00401548 A   _end
0b60 T   _start
00401428 B   environ
0e85 T   main
00401540 B   mut
0dd4 W   pthread_create -> __got_end
0dfd W   pthread_mutex_init -> __data_start
0e10 W   pthread_mutex_lock -> exit
0e1f W   pthread_mutex_unlock -> atexit
 U   puts
 U   sleep
 F   test.c
0e2e T   thread

When compiling with pthread it seems it only resolves 
pthread_mutex_init, but still uses the weak pthread_create and executes 
secondary lock first:
$ gcc -lpthread ./test.c 




$ ./a.out 




Got secondary lock
Released secondary lock
Got main lock
Released main lock
$ nm -e ./a.out 




002012b0 a   _DYNAMIC
00301408 a   _GLOBAL_OFFSET_TABLE_
 W   _Jv_RegisterClasses
004014a8 A   __bss_start
 W   __cxa_atexit -> _dl_searchnum
002010d8 D   __dso_handle
0ff0 T   __fini
00301408 D   __got_start
002010c8 D   __guard_local
0b90 T   __init
 W   __init_tcb -> pthread_mutex_init
002010d0 D   __progname
00401520 B   __progname_storage
0d50 W   __register_frame_info -> (null)
 U   __stack_smash_handler
0c20 T   __start
00401500 B   _dl_skipnum
004014a8 A   _edata
00401628 A   _end
0c20 T   _start
00401508 B   environ
0f45 T   main
00401620 B   mut
0e94 W   pthread_create -> __got_end
0ed0 W   pthread_mutex_lock -> exit
0edf W   pthread_mutex_unlock -> atexit
 U   puts
 U   sleep
 F   test.c
00000eee T   thread

Could someone please elaborate on what I'm doing wrong and how to 
implement these weak symbols properly. Thank you in advance.


Sincerely,

Martijn van Duren