【发布时间】:2013-12-19 05:45:20
【问题描述】:
我在 cxa_finalize 运行程序时遇到崩溃(这是一个程序,而不是其中的库):
$ ./ac-test.exe
Assertion failed: AcLock.cpp(54): AcLock
libc++abi.dylib: terminate called without an active exception
Abort trap: 6
断言/崩溃是由于对象和记录器之间的交互造成的。记录器在对象之前被破坏,但对象使用记录器。因此,弹出断言或崩溃的正在获取的互斥锁已经被破坏(因此pthread_mutex_lock 锁定记录器时失败的原因)。
我已经阅读了 Specifying Attributes of Variables 和 Declaring Attributes of Functions 的 GCC 手册,但我显然遗漏了一些东西。
我将对象和记录器放在访问器中的一个公共标头中,并尝试指定构造顺序:
// AcGlobals.h
static AcLogger& GetLogger() {
static AcLogger logger __attribute__(init_priority(50));
return logger;
}
static AcSocketList& GetAcceptSockets() {
static AcSocketList sockets __attribute__(init_priority(100));
return sockets;
}
这导致了一堆错误:
./AcGlobals.h:24:46: error: expected ';' at end of declaration
static AcLogger logger __attribute__((init_priori...
./AcGlobals.h:24:47: warning: declaration does not declare anything
[-Wmissing-declarations]
static AcLogger logger __attribute__((init_priori...
我也尝试将属性放在函数而不是变量上:
// AcGlobals.h
static AcLogger& GetLogger() __attribute__(init_priority(50)) {
static AcLogger logger;
return logger;
}
static AcSocketList& GetAcceptSockets() __attribute__(init_priority(100)) {
static AcSocketList sockets;
return sockets;
}
这导致了更多问题:
./AcGlobals.h:22:53: warning: GCC does not allow init_priority attribute in this
position on a function definition [-Wgcc-compat]
static AcLogger& GetLogger() __attribute__((init_priority(50))) {
^
./AcGlobals.h:22:53: error: can only use 'init_priority' attribute on file-scope
definitions of objects of class type
我也尝试了__attribute__((constructor(50))) 而不是init_priority,但没有任何乐趣。
注意:我正在使用 Apple 机器。 Apple 有一个“功能”,其中构造函数优先级仅适用于同一文件中的修饰函数和变量。所以这些不能分散在翻译单元中。
如何准确地指定本地静态对象的构造和销毁顺序?
【问题讨论】:
-
你使用的是 GCC 还是 Clang?
-
我两者都用,但以上来自源代码构建的 Clang 3.3。 (我还使用 ICC 和 VS 来尝试删除所有实现定义和未定义的行为)。
-
明智的解决方案是获得更少的全局变量。由于您无法轻松控制全局变量的构建(和销毁)顺序,因此与其跳过无尽的圈子试图让编译器按照您想要的顺序执行此操作,不如创建依赖于其他全局变量的全局变量.
-
@jalf 如果你看一下代码......他的问题不是初始化顺序;他使用 Meyers 单例成语来解决这个问题。这是破坏顺序(因为他的错误在
cxa_finalize,它是在程序结束时调用析构函数的g++函数)。
标签: c++ gcc initialization clang