4 つのコールバック関数を登録しています。
glfwSetMouseButtonCallback(procMouseButton);
glfwSetMousePosCallback(procMousePosition);
glfwSetCharCallback(procCharInput);
glfwSetKeyCallback(procKeyInput);
各コールバック関数は次のようになります。
void GLFWCALL procMouseButton(int button, int action) {
Input::instance().processMouseButton(button, action); // doesn't do anything yet
}
Input
シングルトンです:
Input& Input::instance()
{
static Input instance;
return instance;
}
コールバック関数が登録されると、segfault が発生します。問題を2つに絞り込みました。
最初:プロセス関数のいずれかを除外すると、segfault が消えます。例えば、
// this works
glfwSetMouseButtonCallback(procMouseButton);
//glfwSetMousePosCallback(procMousePosition);
glfwSetCharCallback(procCharInput);
glfwSetKeyCallback(procKeyInput);
// this works also
glfwSetMouseButtonCallback(procMouseButton);
glfwSetMousePosCallback(procMouseButton); // exclude procMousePosition
glfwSetCharCallback(procCharInput);
glfwSetKeyCallback(procKeyInput);
2 番目:ここでシングルトンで宣言されている std::vector をポップまたはプッシュすると、セグメンテーション違反が発生しますEngine
。
class Engine
{
public:
static Engine& instance();
std::list<GameState*> states;
private:
Engine() {}
Engine(Engine const& copy);
Engine& operator=(Engine const& copy);
};
// either causes segfault after registering functions
Engine::instance().states.push_back(NULL);
Engine::instance().states.pop_front();
私は完全に困惑しています。問題は静的初期化順序の大失敗に関連していると思いますが、修正方法がわかりません。このエラーが発生する理由を説明できる人はいますか?
重要事項:
- リンクの順序を逆にすると、セグメンテーション違反はなくなります。
- コンパイルには MinGW/GCC を使用しています。
- シングルスレッドで実行しています。
- シングルトンにはデフォルトのコンストラクターがなく、すべてがによって初期化されます
Singleton::instance().initialize();
- 正確な segfault コール スタック:
0047B487 std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*) ()
00000000 0x00401deb in std::list >::_M_insert()
00000000 0x00401dbb in std::list >::push_back()
00401D92 Engine::pushState(GameState*) ()
00404710 StartupState::initialize() ()
00402A11 Engine::initialize() ()
00000000 0x00403f29 in main()