使用全局对象时崩溃,但使用本地对象时不会崩溃

Crash when using a global object, but not when using a local object

本文关键字:对象 崩溃 全局      更新时间:2023-10-16

我正在尝试使用libconfig为我的程序创建配置文件。有两种情况,一种可以完美起作用(本地范围对象),另一个可以通过失败(全局范围对象)。我试图理解为什么一个人在另一个成功时失败,因为我的理解是两者都是创建相同对象的定义(仅在不同的范围中)。

1st(不起作用):我在全局范围中定义了配置对象。然后,我在配置对象上调用ReadFile。该程序在这里崩溃。

#include <libconfig.h++>
libconfig::Config cfg;
int __attribute__((constructor)) Init()
{
  cfg.readFile("/home/jalius/csgo-internal/hack.cfg");
}

第二(工作):我定义了本地配置对象并在其上调用readfile。

#include <libconfig.h++>
int __attribute__((constructor)) Init()
{
  libconfig::Config cfg;
  cfg.readFile("/home/jalius/csgo-internal/hack.cfg");
}

当时在调用int __attribute__((constructor)) Init()函数时,在您的情况下,cfg对象不是创建。因为未指定使用属性constructor和具有静态存储持续时间的C 对象的呼叫功能的顺序。由于对象不存在,因此您会收到分割故障错误,即SIGSEGV信号。

以下是GCC网站的摘录:

目前,未指定使用静态存储持续时间和具有属性constructor功能的C 对象的构造函数。在混合声明中,属性init_priority可用于施加特定的订单。

有关更多信息,请参见此页面上的constructor部分。

无法保证您的函数int __attribute__((constructor)) Init()在构建 Config对象之前将被称为

当您尝试从中读取它时,实际上可能尝试访问未构造的对象。这将导致不确定的行为。

当您在本地创建它时,可以保证您的对象在使用之前将完全初始化。


实验:

#include <iostream>
enum {
    OBJECT_CONSTRUCTOR,
    FUNCTION_CONSTRUCTOR,
};
int order[10], cur = 0;
class TestClass {
  public:
   TestClass() { order[cur++] = OBJECT_CONSTRUCTOR; }
   ~TestClass() { }
};
TestClass abc;
int __attribute__((constructor)) Init() {
   order[cur++] = FUNCTION_CONSTRUCTOR;
}
int main ()
{
    std::cout << "Order of execution:n";
    for(int i = 0; i < cur; i++)
    {
        switch(order[i])
        {
            case OBJECT_CONSTRUCTOR:
                std::cout<<"Object Constructorn";
                break;
            case FUNCTION_CONSTRUCTOR:
                std::cout<<"Function Constructorn";
                break;
        }
    }
    return 0;
}

结果:

Order of execution:
Function Constructor
Object Constructor