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 <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
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
00000f30 T __fini
00301338 D __got_start
00201008 D __guard_local
00000ad0 T __init
W __init_tcb
00201010 D __progname
00401440 B __progname_storage
00000c90 W __register_frame_info -> (null)
U __stack_smash_handler
00000b60 T __start
00401420 B _dl_skipnum
004013d8 A _edata
00401548 A _end
00000b60 T _start
00401428 B environ
00000e85 T main
00401540 B mut
00000dd4 W pthread_create -> __got_end
00000dfd W pthread_mutex_init -> __data_start
00000e10 W pthread_mutex_lock -> exit
00000e1f W pthread_mutex_unlock -> atexit
U puts
U sleep
00000000 F test.c
00000e2e 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
00000ff0 T __fini
00301408 D __got_start
002010c8 D __guard_local
00000b90 T __init
W __init_tcb -> pthread_mutex_init
002010d0 D __progname
00401520 B __progname_storage
00000d50 W __register_frame_info -> (null)
U __stack_smash_handler
00000c20 T __start
00401500 B _dl_skipnum
004014a8 A _edata
00401628 A _end
00000c20 T _start
00401508 B environ
00000f45 T main
00401620 B mut
00000e94 W pthread_create -> __got_end
00000ed0 W pthread_mutex_lock -> exit
00000edf W pthread_mutex_unlock -> atexit
U puts
U sleep
00000000 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