如何在编译时获得thread_local变量的偏移量

时间:2016-04-29 11:18:50

标签: c++ gcc thread-local

在linux下使用gcc,我正在寻找一种方法来获取相对于线程本地存储区域的线程局部变量的偏移量。 该偏移量是编译的目标文件中包含的内容。 在我看来应该有一个宏或build_in才能得到它。

运行时给出的代码如下所示。我需要的是在编译时获得该常量。

#include <iostream>
#include <thread>

thread_local int x;

template<typename T>
intptr_t getOffset(T& t){
    return (intptr_t)&t-(intptr_t)pthread_self();
}

int main(int argc, char **argv)
{       
    std::cout<<"offset:"<<getOffset<int>(x)<<std::endl;
}

1 个答案:

答案 0 :(得分:0)

  

我认为应该有一个宏或Built_in才能获取它。

这样的宏将不容易/廉价地实现。首先,您只能在编译可执行文件时确定此类偏移量,因为对于动态库,它取决于库在加载它的可执行文件的依赖项列表中的相对位置(如果通过{{1动态加载库,则甚至不在静态TLS块中) }},因此无法通过与TCB保持恒定的偏移量来访问。

现在,即使您尝试确定可执行文件中的偏移量,也只能对可执行文件本身中的<table class="table table-striped table-bordered"> <thead> <tr> <th width="15%">Mašina</th> <th width="15%">Išduota</th> <th width="15%">Grąžinta</th> <th width="20%">Vairuotojas</th> <th width="10%">Neaktualus</th> <th width="15%">Perdavimo aktas</th> <th width="10%">Veiksmai</th> </tr> </thead> <tbody class="paste_place"> <tr class="copy_item"> <td><input type="text" name="masina[]" class="form-control" placeholder="Įveskite..." /></td> <td><input type="text" name="isduota[]" class="form-control datepicker" placeholder="Įveskite..." /></td> <td><input type="text" name="grazinta[]" class="form-control datepicker" placeholder="Įveskite..." /></td> <td> <select class="form-control select-remote-vairuotojai" name="vairuotojas[]"> <option value="">Pasirinkite iš sąrašo</option> </select> </td> <td><input type="text" name="neaktualus[]" class="form-control" placeholder="Įveskite..." /></td> <td>haha</td> <td><a onclick="add_column('copy_item', 'paste_place');"><i style="font-size: 20px;" class="icon-plus-circle2"></i></a> &nbsp;<a onclick="remove_column(this, 'paste_place');"><i style="font-size: 20px; color: red;" class="icon-minus-circle2"></i></a></td> </tr> </tbody> </table>变量执行此操作,因为库的thread_local段的大小(及其偏移量)仅在程序启动时确定(即可能是因为已加载库的版本可能比可执行文件所链接的版本要新,因此dlopen段的大小也可能有所不同。

最后,即使对于可执行文件的变量,它也将取决于链接期间目标文件和静态/动态库的相对顺序,因此您需要静态链接器中的特殊支持来计算偏移量。

您可能会建议Binutils开发人员考虑添加链接时重定位来计算可执行文件中的thread_local偏移量,或者甚至在一般情况下甚至添加运行时重定位来计算thread_local,但他们将需要令人信服的用例来考虑此类建议。

作为穷人的解决方法,您可以编译两次代码,并从symtab中提取偏移量:

thread_local