progschj / ThreadPool

A simple C++11 Thread Pool implementation
zlib License
7.63k stars 2.21k forks source link

Differences between dynamic linking and static linking for ThreadPool #108

Open AlexSJJ opened 8 months ago

AlexSJJ commented 8 months ago

I'm a novice programmer and I've encountered an issue while working with this project. When I compile the project using: ubuntu 1804

g++ -static -o example example.cpp -lpthread I encounter a "Segmentation fault (core dumped)" error. Thread 2 "example" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7ffff7ff9700 (LWP 7905)] 0x0000000000000000 in ?? () (gdb) bt

0 0x0000000000000000 in ?? ()

1 0x000000000046cb2c in std::condition_variable::wait(std::unique_lock&) ()

2 0x0000000000406692 in std::condition_variable::wait<ThreadPool::ThreadPool(unsigned long)::{lambda()#1}::operator()() const::{lambda()#1}>(std::unique_lock&, ThreadPool::ThreadPool(unsigned long)::{lambda()#1}::operator()() const::{lambda()#1}) (this=0x7fffffffe290, lock=..., p=...) at /usr/include/c++/7/condition_variable:99

3 0x000000000040587b in ThreadPool::ThreadPool(unsigned long)::{lambda()#1}::operator()() const (__closure=0x601b38)

at ThreadPool.h:43

4 0x000000000040a59f in std::invoke_impl<void, ThreadPool::ThreadPool(unsigned long)::{lambda()#1}>(std::__invoke_other, ThreadPool::ThreadPool(unsigned long)::{lambda()#1}&&) (f=...) at /usr/include/c++/7/bits/invoke.h:60

5 0x0000000000409bb8 in std::invoke<ThreadPool::ThreadPool(unsigned long)::{lambda()#1}>(std::invoke_result&&, (ThreadPool::ThreadPool(unsigned long)::{lambda()#1}&&)...) (__fn=...) at /usr/include/c++/7/bits/invoke.h:95

6 0x000000000040c54c in std::thread::_Invoker<std::tuple<ThreadPool::ThreadPool(unsigned long)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (this=0x601b38) at /usr/include/c++/7/thread:234

7 0x000000000040c4cc in std::thread::_Invoker<std::tuple<ThreadPool::ThreadPool(unsigned long)::{lambda()#1}> >::operator()() (this=0x601b38) at /usr/include/c++/7/thread:243

8 0x000000000040c3b2 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<ThreadPool::ThreadPool(unsigned long)::{lambda()#1}> > >::_M_run() (this=0x601b30) at /usr/include/c++/7/thread:186

9 0x00000000004434df in execute_native_thread_routine ()

10 0x000000000040dabb in start_thread (arg=0x7ffff7ff9700) at pthread_create.c:463

11 0x0000000000526e9f in clone ()

However, when I compile it without the static flag:

g++ -o example2 example.cpp -lpthread it runs perfectly fine. I'm trying to understand the difference and why this is happening. Could someone please explain this to me?

lix19937 commented 2 months ago

So please use -pthread as a flag and not -lpthread.

This behavior is also mentioned in the following, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59830

There's a difference between -pthread and -lpthread.
Looking at the man page for g++

-pthread
Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker.

To have a look to what flags are activated for both one can check with the following:

g++ -dumpspecs | grep pthread
g++ -dumpspecs | grep lpthread

As one can clearly see, there are some preprocessor macros that are not activated if one is using -lpthread.

ref https://stackoverflow.com/questions/41790363/c-core-dump-with-packaged-task