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

Что: 32de5099caa3ce8930ed93a223d62f608a126118

Когда: 2023-08-26 15:11:00+03:00

Темы: 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


>А как 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-овые.

Сгенерирован: SGBlog 0.34.0