相同的C ++代码在g ++ 4.6编译器中工作,但与5.1崩溃

时间:2015-07-27 09:53:30

标签: c++ g++

以下代码与g ++ 4.6编译器一起使用,但在使用g ++ 5.1编译器编译时崩溃并出现分段错误。变量访问gString导致分段错误。

#define _GLIBCXX_DEBUG 1
#define _GLIBCXX_USE_CXX11_ABI 0

#include<string>
#include<iostream>
#include<vector>

static std::string gString("hello");

static void
__attribute__((constructor))
initialize()
{
    gString.assign("hello world");
    return;
}

static void 
__attribute__((destructor)) 
finalize()
{
    return;
}

int main(int ac, char **av)
{
    //std::cerr<<gString;
    return 0;
}

GDB输出:

   Reading symbols from /home/rk/str...done.
(gdb) b initialize
Breakpoint 1 at 0x401419: file str.cc, line 15.
(gdb) r 
Starting program: /home/rk/str 

Breakpoint 1, initialize() () at str.cc:15
15      gString.assign("hello world");
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x00000000004018d6 in std::string::size() const () at /usr/include/c++/5/bits/basic_string.h:3118
3118          { return _M_rep()->_M_length; }
(gdb) bt
#0  0x00000000004018d6 in std::string::size() const () at /usr/include/c++/5/bits/basic_string.h:3118
#1  0x00000000004016ff in std::string::assign(char const*, unsigned long) () at /usr/include/c++/5/bits/basic_string.tcc:706
#2  0x000000000040166e in std::string::assign(char const*) () at /usr/include/c++/5/bits/basic_string.h:3542
#3  0x0000000000401428 in initialize() () at str.cc:15
#4  0x00000000004023dd in __libc_csu_init ()
#5  0x00007ffff71ad700 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#6  0x0000000000401289 in _start ()

2 个答案:

答案 0 :(得分:4)

为什么在C ++中使用__attribute__((constructor))而不是简单地使用构造函数的全局对象?这些属性在C代码中很有用,但在C ++中是多余的。

问题是你的构造函数在初始化标准iostream之前运行,如果你使用带有构造函数的全局对象,这不会有问题。

您可以尝试为构造函数添加优先级,但我认为在这种情况下它不会有用:

__attribute__((constructor(999))) 

答案 1 :(得分:3)

gcc 4.9.2也会发生运行时错误(参见ideone示例)。

问题与尚未初始化的iostream有关。评论cerr行,一切正常

显然,它是known issue

编辑:补充说明

这个小workaround似乎有效,至少4.9:使用c stdio代替iostreams:

fprintf(stderr, "_initialize");  // this works

但我完全同意Jonathan关于使用完全依赖于明确定义的标准C ++行为的全局(单例?)对象的建议,除非您确实需要在动态库加载时正好运行构造函数。