gcc升级导致模板函数的静态局部变量变得不可知

时间:2017-07-04 07:23:15

标签: c++ gcc compilation

我将gcc从gcc 4.1.2升级到gcc 4.9.4。

我首先用gcc4.9编译,然后启动程序,看到下面的错误:

user@machine:~/bin> Load BusinessSoCfg, Name GameSvr, Dll ../SO/so, CreateFunc CreateBusinessSo
Open Dll ../SO/so failed, ../SO/so: undefined symbol: _ZZN6CTable24IsGameTableSOSupportFuncIM5IGameFiisiiP13tagSOItemInfoEEEbT_E7pHandle

pHandle是模板函数中定义的静态变量。 代码是这样的:

template<class TPMF>
bool CTable::IsGameTableSOSupportFunc(TPMF pfunc)
{
     static void *pHandle = NULL;
     // somethign todo
     return true;
}

在我们的测试环境(gcc4.1.2)上,nm-cn如下所示,表示符号是未知类型

0000000004d1d9d0 ? bool CTable::IsGameTableSOSupportFunc<int (IGame::*)(int, short, int, int, tagSOItemInfo*)>(int (IGame::*)(int, short, int, int, tagSOItemInfo*))::pHandle

但是在编译环境(gcc4.9.4)nm -C所以显示如下,显示符号已定义

0000000004d1d9d0 u bool CTable::IsGameTableSOSupportFunc<int (IGame::*)(int, short, int, int, tagSOItemInfo*)>(int (IGame::*)(int, short, int, int, tagSOItemInfo*))::pHandle

更重要的是,gcc4.9.4是使用gcc4.1.2从源代码编译的,配置如下:

$ ./configure --prefix=/data/gcc-4.9.4/ --enable-languages=c,c++ --enable-lto --enable-vtable-verify --disable-libquadmath-support --disable-libada

causion:以下示例未显示与上述相同的结果

示例:

//singleton.hpp, must be a hpp
// if singleton was defined in the same file with main,everything goes fine
#include <stdio.h>
#include <stdlib.h>


template <class TYPE>
class CSingleton
{
public:
    static TYPE* Instance(void)
    {
        if(m_pSingleton == NULL)
        {
            CSingleton *pTmpCSingleton = new CSingleton;
            m_pSingleton = pTmpCSingleton;
        }
        return &m_pSingleton->m_stInstance;
    }
protected:
    TYPE m_stInstance;
    static CSingleton<TYPE>* m_pSingleton;
};

template <class TYPE>
CSingleton<TYPE>* CSingleton<TYPE>::m_pSingleton = NULL;

// main.cpp
// if singleton was defined in the same file with main,everything goes fine
#include "singleton.hpp" 
#include <stdio.h>
typedef CSingleton<int> s;
int main(){
    printf("%d\n", *s::Instance());
    return 0;
}

使用gcc4.9编译,运行结果为:0

但是当我将二进制文件复制到gcc4.1.2机器时,执行将是核心。

Floating point exception (core dumped)

fathermore nm -C会显示错误:

nm: a.out: File format not recognized

但两台机器上的readelf工作正常:

ELF Header:
Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
Class:                             ELF64
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              EXEC (Executable file)
Machine:                           Advanced Micro Devices X86-64
Version:                           0x1
Entry point address:               0x400520
Start of program headers:          64 (bytes into file)
Start of section headers:          3072 (bytes into file)
Flags:                             0x0
Size of this header:               64 (bytes)
Size of program headers:           56 (bytes)
Number of program headers:         8
Size of section headers:           64 (bytes)
Number of section headers:         30
Section header string table index: 27

1 个答案:

答案 0 :(得分:0)

这是由gcc升级引起的。从较高gcc版本编译的二进制文件使用gnu哈希。但运行计算机的binutil无法识别。使用-Wl,--hash-style=both-Wl,--hash-style=sysv重新编译可以解决此问题。

如果我早点看核心文件,我可以更快地解决这个问题。