Статическая линковка с 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
- ** 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-овые.
Сгенерирован: SGBlog 0.34.0