[О блоге] [наверх] [пред] [2023-08-26 15:11:00+03:00] [32de5099caa3ce8930ed93a223d62f608a126118]
Темы: [c][hate][tip]

Статическая линковка с pthread

https://stackoverflow.com/questions/35116327/when-g-static-link-pthread-cause-segmentation-fault-why
Под FreeBSD добавление -static для одной моей программы было достаточно,
чтобы статически слинковать и оно работало. Под GNU/Linux -- хрен мне,
конечно же. Линкует, запускает, но при попытке взять lock в pthread-е
выдаёт ошибку. "-Wl,--whole-archive -lpthread -Wl,--no-whole-archive"
помог, но сам бы я до этого не допёр.

    [оставить комментарий]
    комментарий 0:
    From: kmeaw
    Date: 2023-08-27 10:38:10Z
    
    > For example, fputc (conceptionally used by printf) is required by
    > POSIX to be thread-safe and needs to be synchronized, which is costly.
    > In a single-threaded environment, you do not want to pay the costs. An
    > implementation could therefore implement the synchronization functions
    > as empty stubs, and declare the functions as weak symbols.
    
    А как libc у FreeBSD решает эту проблему?
    
    комментарий 1:
    From: Sergey Matveev
    Date: 2023-08-28 08:10:07Z
    
    *** kmeaw [2023-08-27 11:37]:
    >А как libc у FreeBSD решает эту проблему?
    
    Для pthread-ов используется libthr реализация. В man-говорится:
    
        INTERACTION WITH RUN-TIME LINKER
         On load, libthr installs interposing handlers into the hooks exported by
         libc.  The interposers provide real locking implementation instead of the
         stubs for single-threaded processes in libc, cancellation support and
         some modifications to the signal operations.
    
    Судя по коду libthr, в __thr_interpose_libc он вызывает
    __libc_interposing_slot для переопределения всяких syscall-ов в libc
    (accept, ..., pdfork) на свои __thr_* реализации. __thr_interpose_libc
    вызывается в _libpthread_init, который:
    
        /*
         * Threaded process initialization.
         *
         * This is only called under two conditions:
         *
         *   1) Some thread routines have detected that the library hasn't yet
         *      been initialized (_thr_initial == NULL && curthread == NULL), or
         *
         *   2) An explicit call to reinitialize after a fork (indicated
         *      by curthread != NULL)
         */
        void
        _libpthread_init(struct pthread *curthread)
    
    Кто вызывает всю эту инициализацию с самого начала: с ходу не нашёл в
    коде. Но вижу что в (Free)BSD libc много где используется "extern int
    __isthreaded", прямо в stdio.h например для использования или threaded
    или не-threaded версии функций. Внутри Си-шных функций аналогично
    проверкиа на "if (__isthreaded)" есть. А также libc явно знает про
    libthr существование. То бишь, судя по всему, функции просто понимаю и
    знают в threaded режиме ли они или нет, и если да, то инициализируется
    явно libthr, устанавливающий hook-и на функции связанные с pthread. nm
    показывает что weak символов нет (только пара отладочных) в libpthread.a.
    Насколько понимаю, всё в run-time, а не во время линковки заменяется с
    stub reentrant-related вещей на настоящие libthr-овые.