When g statically links pthread, causing Segmentation fault, why?
In static linking, the linker will stop at the first symbol, even if it is a weak one, and stops looking for strong ones. To force it to look at all symbols (like it would have done for a dynamically linked library), ld supports the --whole-archive option.
The following command will work:
g++ -o one one.cpp -Wall -std=c++11 -O3 -static -pthread \ -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
Here's what's happening:
Understanding weak symbols
ELF file format has the concept of weak and strong symbols. By default, symbols in an object file are strong. During linking, a strong symbol can override a weak symbol of the same name.
In the case of glibc and pthreads, they use weak symbols. For example, fputc 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 these costs. An implementation could therefore implement the synchronization functions as empty stubs, and declare the functions as weak symbols.
Later, if a multi-threading library is linked (e.g., pthread), it becomes obvious that single-thread support is not intended. When linking the multi-threading library, the linker can then replace the stubs by the real synchronization functions (defined as strong symbols and implemented by the threading-library).
Applying this to the example program
The libc.a library contains __pthread_mutex_lock as a weak symbol, and the libpthread.a library contains it as a strong symbol. When linking dynamically, the linker replaces the weak symbol with the strong symbol. However, when linking statically, you need to enforce the same semantic. That's why -Wl,--whole-archive -lpthread -Wl,--no-whole-archive is needed.
The above is the detailed content of Why does statically linking pthread with g lead to a segmentation fault, and how can I resolve it using the `--whole-archive` option?. For more information, please follow other related articles on the PHP Chinese website!