gcc: локальная переменная потока, скомпилированная как BSS

Я новичок и тестирую класс локального хранилища (TLS) с gcc (версия 4.8.2) на моем компьютере с Ubuntu 14.04 с архитектурой i686/32 bit.

В попытке выяснить, является ли __thread Ключевое слово имеет желаемый эффект, я собираю эту минималистичную тестовую программу с gcc test.c (без ошибок или предупреждений):

#include <stdio.h>

__thread int i;

int main() {
  i = 7;
  printf("%d\n",i);
}

и использовать инструмент nm проверить класс хранения символа i в коде объекта:

nm a.out | grep ' i'

Результат

00000000 B i

Который означает, что i рассматривается как общая глобальная неинициализированная переменная (хранится в разделе BSS). В соответствии с man nm, переменные локального хранилища потока обозначаются буквой Lне B,

Что здесь не так?

Это nm проблема или реальная проблема?

2 ответа

Решение

Там нет проблем, это просто способ nm(1) пишет вывод.

nm(1)Формат вывода по умолчанию (и информация) отличается на разных платформах (например, на странице man для nm(1) в моем рабочем столе Linux даже не упоминает L для локального потока).

Однако, если вы включите выходной формат SysV с -fs, вы получите более подробный вывод:

$ nm -fs a.out
Symbols from a.out:

Name                  Value           Class        Type         Size             Line  Section

...

i                   |0000000000000000|   B  |               TLS|0000000000000004|     |.tbss
...

Как вы можете видеть, используя этот формат вывода i идентифицируется как локальный поток под столбцом Typeи живет в .tbss,

Если на странице вашего дистрибутива упоминается L флаг для локального хранилища потока, и вы не видите его в формате вывода по умолчанию, я бы сказал, что это ошибка в nm(1),

Ваш код слишком минимален. Количество потоков не будет известно до времени выполнения, поэтому переменная, которую вы видите в исполняемом файле, является переменной, которая main буду использовать. Дополнительные копии переменной будут выделяться при создании дополнительных потоков.

Вот минимальная программа, которая демонстрирует переменные потока.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

__thread int i;

void *foo( void *args )
{
    i = 8;
    printf( "foo: %d\n", i );
    return NULL;
}

int main( void )
{
    i = 7;
    printf( "main:%d\n", i );

    pthread_t pid;
    if ( pthread_create( &pid, NULL, foo, NULL ) != 0 )
        exit( 1 );

    pthread_join( pid, NULL );
    printf( "main:%d\n", i );
}
Другие вопросы по тегам