【问题标题】:GCC Common Variable Attribute on TLS modelTLS 模型上的 GCC 通用变量属性
【发布时间】:2020-08-26 02:18:54
【问题描述】:

参考GCC website。据说

tls_model 属性设置特定 __thread 变量的线程本地存储模型(请参阅 Thread-Local),在每个变量的基础上覆盖 -ftls-model= 命令行开关。 tls_model 参数应该是 global-dynamic、local-dynamic、initial-exec 或 local-exec 之一。并非所有目标都支持此属性。

为了查看为不同 TLS 模型生成的程序集的差异,创建了一个包含三个 __thread 变量的类。

#include <cstdint>

class Holder
{
public:
    static int32_t calc();
    static int32_t calc2();
    static int32_t calc3();
    static __thread int32_t value  __attribute__ ((tls_model("initial-exec")));
    static __thread int32_t value2  __attribute__ ((tls_model("local-dynamic")));
    static __thread int32_t value3;
};

__thread int32_t Holder::value;
__thread int32_t Holder::value2;
__thread int32_t Holder::value3;

int32_t Holder::calc()
{
    return value * 2;
}

int32_t Holder::calc2()
{
    return value2 * 2;
}

int32_t Holder::calc3()
{
    return value3 * 2;
}

这是使用-c -shared -fPIC -O3 标志编译的。但是,请注意,该属性不会在相应的计算函数中产生任何差异。 (在相应的计算函数中都使用__tls_get_addr。)但是,如果添加了-ftls-model=initial-exec 标志,它确实会改变TLS 模型,但都会被覆盖以使用inital-exec(所有计算函数都使用@gottpoff(%rip)

使用在线编译器资源管理器,发现 clang (LLVM) 和 icc 似乎都尊重属性,但不尊重 gcc。它似乎也与 GCC 网站中的描述相矛盾(基于每个变量覆盖)。可以在this 上试用并切换到不同的编译器。

GCC 是否有理由删除了覆盖每个变量设置的能力?还是我做错了什么或有错误的期望?

提前感谢您的帮助和解释。

【问题讨论】:

  • 这是在 Linux 上,对吧?我添加了那个标签。我假设基于@gottpoff(%rip) - 我认为无论 Windows 使用什么都不称为 GOT,但我不确定 MacOS。
  • 是的,它在 Linux 上。感谢您添加标签。

标签: linux gcc x86-64 thread-local-storage


【解决方案1】:

这是一个错误,可能在 C++ 前端和/或属性合并代码中。如果您从定义的声明中移动或复制属性,它会按预期工作。如果您消除定义,只留下声明,它也可以根据文档工作。基本上,每个定义似乎都没有从前面的声明中正确继承属性。这值得在https://gnu.gnu.org/bugzilla 进行错误报告

【讨论】:

  • 或者是UB从定义中省略属性?这将解释编译器之间的差异。 (尽管在这种情况下,您希望 GCC 至少会在 -Wall 发出警告。)
  • @PeterCordes 通常 GCC 要么合并属性列表,要么在合并没有意义或不支持的情况下发出诊断信息,因此像这里一样默默地删除属性不是预期的行为。
  • 感谢您指出,如果属性位于定义而不是声明中,则该属性有效。
  • 声明上的属性似乎没有被完全忽略。当编译另一个包含声明中包含 tls_model 属性的标头的文件时,程序集似乎为该目标文件使用了正确的模型。
  • @Steven 当同时存在定义和声明(或两个声明)并且 GCC 需要合并它们的属性列表时,就会出现问题。毫不奇怪,在另一个文件中它可以正常工作,因为那里只有一个声明。
猜你喜欢
  • 1970-01-01
  • 2018-03-30
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
相关资源
最近更新 更多