2017-12-11 24 views
2

libconfigを使用して自分のプログラムの構成ファイルを作成しようとしています。完全に動作する(ローカルスコープオブジェクト)シナリオと、失敗するシナリオ(グローバルスコープオブジェクト)の2つのシナリオがあります。私は両方が同じオブジェクト(ちょうど異なる範囲)を作成する定義であるという私の理解であるので、他が成功している間に1つが失敗する理由を理解しようとしています。グローバルオブジェクトを使用するとクラッシュしますが、ローカルオブジェクトを使用するとクラッシュしません

1番目(動作しません):グローバルスコープでConfigオブジェクトを定義します。次に、ConfigオブジェクトのreadFileを呼び出します。ここでプログラムがクラッシュします。

#include <libconfig.h++> 

libconfig::Config cfg; 

int __attribute__((constructor)) Init() 
{ 
    cfg.readFile("/home/jalius/csgo-internal/hack.cfg"); 
} 

2番目(動作中):ローカルのConfigオブジェクトを定義し、それに対してreadFileを呼び出します。

#include <libconfig.h++> 

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

ランタイムエラーとは何ですか? – Yashas

+0

どのように情報を抽出するのですか?この共有ライブラリはdlopenで別のプロセスに注入されます。私はプロセスでgdbを開いて、メインスレッドがlibconfig.cの中でSIGSEGVを受け取ったことを確認します(私はデバッグシンボルを持っていません)。 –

+0

「SIGSEGV」信号はセグメンテーションフォルトを表します。 – Yashas

答えて

2

あなたがあなたのケースにcfgオブジェクトがが作成されていない当時のint __attribute__((constructor)) Init()関数を呼び出しています。属性constructorで装飾された関数を呼び出す順序と、静的記憶域期間を持つC++オブジェクトの順序が不定であるためです。オブジェクトは存在しないため、セグメンテーションフォールトエラー、つまりSIGSEGVシグナルが得られます。続い

GCC websiteからの抽出物である:

現在、属性constructor飾ら静的記憶域期間と機能を持つC++オブジェクトが呼び出されるのコンストラクタ順序が指定されていません。複合宣言では、属性init_priorityを使用して特定の順序付けを行うことができます。

constructorセクションのthis pageを参照してください。

1

Configオブジェクトが構築されて前に、あなたの関数int __attribute__((constructor)) Init()が呼び出される保証はありません。

実際に読み込もうとすると、実際には構造化されていないオブジェクトにアクセスしようとする可能性があります。これにより未定義の動作が発生します。

ローカルで作成する場合、オブジェクトを使用する前に完全に初期化されるという保証があります。


実験:

#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 Constructor\n"; 
       break; 
      case FUNCTION_CONSTRUCTOR: 
       std::cout<<"Function Constructor\n"; 
       break; 
     } 
    } 
    return 0; 
} 

結果:

Order of execution: 
Function Constructor 
Object Constructor 
+0

興味深い。私は、すべてのグローバル変数がmainと同じように構築されることが保証されると仮定しました。 –

+0

投稿したコードは役に立ちました:) –

関連する問題