Reputation: 90
I am currently a student and learning about operating systems and using Linux as the OS to practice on. When we got to multi-threaded applications and started to practice with them (mainly just pthread_create() and pthread_join() ), one of the most common errors the class got was that when compiling they used:
gcc -Wall homework.c
instead of:
gcc -Wall -lpthread homework.c
My question is why the compiler and linker don't throw an error when not compiled/linked with -lpthread specifier even though the functions used in the code require the pthread library. My instructor doesn't seem to know the reason either. Is it just the way the school has set up our system? Does that happen with all Linux environments? Why is no linker error thrown?
Upvotes: 4
Views: 134
Reputation: 1174
Addition hypothesis to @FelixPalmen's answer. pthread
can passed to linker as declared in gcc's specs. gcc can use built-in specs or reading it from file.
By default on my system linker print errors while I try building sample without -lpthreads
:
serga@XXXXX:~$ gcc ./thread.c -o thread
/tmp/ccHgCRzO.o: In function `main':
thread.c:(.text+0x29): undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
First of all I detect which files gcc tries to use as spec:
serga@XXXXX:~$ strace gcc 2>&1 | grep spec
access("/usr/lib/gcc/i686-linux-gnu/5/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/i686-linux-gnu/5/../../../../i686-linux-gnu/lib/i686-linux-gnu/5/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/i686-linux-gnu/5/../../../../i686-linux-gnu/lib/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/i686-linux-gnu/specs", R_OK) = -1 ENOENT (No such file or directory)
Then I create my own spec getting build-in one and place it into path that gotten in previous step:
serga@XXXXX:~$ sudo gcc -dumpspecs >/usr/lib/gcc/i686-linux-gnu/5/specs
I inserted one by one -lpthread
into *link:
, *lib:
and *libgcc:
sections of spec-file. In all cases gcc can build program without explicit mention for pthread library:
serga@XXXXX:~$ gcc ./thread.c -o thread && echo "completed"
completed
Gotcha!!!
Need to see output of the next (I used gcc-5.1.0):
serga@XXXXX:~$ gcc -v 2>&1 | head -1
If gcc uses spec from specific file you'll see the next:
Reading specs from /usr/lib/gcc/i686-linux-gnu/5/specs
Otherwise:
Using built-in specs.
You can see build-in specs doing this:
serga@XXXXX:~$ gcc -dumpspecs
Need to see inside gotten spec file any appearance of -lpthread
in sections related to the linker.
Upvotes: 0
Reputation:
Can't reproduce:
#include <pthread.h>
void *thread(void *arg)
{
(void) arg;
return 0;
}
int main(void)
{
pthread_t t;
pthread_create(&t, 0, thread, 0);
return 0;
}
Trying to link without libpthread
:
> gcc -Wall -o thread thread.c
/tmp/ccyyu0cn.o: In function `main':
thread.c:(.text+0x2e): undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
edit: you can check the symbols defined in a library with nm -D
, e.g. in my case:
> nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep pthread_create
> nm -D /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
00000000000082e0 T pthread_create
(so pthread_create
is not found in libc
, but indeed in libpthread
)
edit2: The only possible reason for the behavior you claim to observe would be that one of the libraries linked per default (libc
, maybe libgcc
) defines pthread_create
. Then it would probably still be dependent on things only defined in libpthread
. I now wonder whether this really is the case for some particular version. Please give feedback.
Upvotes: 2