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

Reply via email to