I am new to and testing the thread-local storage (TLS) class with gcc
(version 4.8.2) on my Ubuntu 14.04 computer with i686/32 bit architecture.
In trying to find out whether the __thread
keyword has the desired effect, I compile this minimalistic test program with gcc test.c
(no errors or warnings):
#include <stdio.h>
__thread int i;
int main() {
i = 7;
printf("%d\n",i);
}
and use the tool nm
to check the storage class of the symbol i
in the object code:
nm a.out | grep ' i'
The result is
00000000 B i
which means that i
is treated as a common global uninitialized variable (stored in the BSS section). According to man nm
, thread local storage variables are denoted by the letter L
, not B
.
What's wrong here?
Is this an nm
problem or a real problem?
There's no problem, it's just the way nm(1)
writes output.
nm(1)
's default output format (and information) is different among platforms (for example the manpage for nm(1)
in my Linux desktop doesn't even mention L
for thread-local storage).
However, if you enable SysV output format with -fs
, you get a more verbose output:
$ nm -fs a.out
Symbols from a.out:
Name Value Class Type Size Line Section
...
i |0000000000000000| B | TLS|0000000000000004| |.tbss
...
As you can see, using this output format i
is identified as being thread local under the column Type
, and it lives in .tbss
.
If the manpage for your distribution mentions the L
flag for thread-local storage and you don't see it in the default output format, I'd say it's a bug in nm(1)
.