誰かが次ワンセグfautlを理解することに役立ち、また、なぜそれがリンク順序の変更に関する作業しことができます:ワンセグ障害グローバルオブジェクトの静的メンバを使用して
COMMON.Hファイル:
#include <set>
struct T {
explicit T(const char*) {
Instances.insert(this);
}
static std::set<T*> Instances;
};
dは。 CCファイル:
#include "common.h"
T d(__FILE__);
main.ccファイル:
#include "common.h"
#include <set>
#include <iostream>
/*static*/ std::set<T*> T::Instances;
int main() {
std::cout << "T::Instances.size() = " << T::Instances.size() << std::endl;
while(true);
}
構築し、次のコマンドを実行している:だから
$ ./app
Segmentation fault (core dumped)
$ gdb ./app
(gdb) run
Starting program: /home/meodou/zdev/poc_at_7405/testi/app
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7afebca in std::local_Rb_tree_decrement (__x=0x6031e8 <T::Instances+8>) at ../../../../../libstdc++-v3/src/c++98/tree.cc:98
98 && __x->_M_parent->_M_parent == __x)
(gdb) bt
#0 0x00007ffff7afebca in std::local_Rb_tree_decrement (__x=0x6031e8 <T::Instances+8>) at ../../../../../libstdc++-v3/src/c++98/tree.cc:98
#1 0x0000000000401365 in std::_Rb_tree_iterator<T*>::operator-- (this=0x7fffffffdc50) at /usr/include/c++/5.3.1/bits/stl_tree.h:220
#2 0x000000000040102f in std::_Rb_tree<T*, T*, std::_Identity<T*>, std::less<T*>, std::allocator<T*> >::_M_get_insert_unique_pos (
this=0x6031e0 <T::Instances>, [email protected]: 0x6031d1 <d>) at /usr/include/c++/5.3.1/bits/stl_tree.h:1819
#3 0x0000000000400dfe in std::_Rb_tree<T*, T*, std::_Identity<T*>, std::less<T*>, std::allocator<T*> >::_M_insert_unique (this=0x6031e0 <T::Instances>,
[email protected]: 0x6031d1 <d>) at /usr/include/c++/5.3.1/bits/stl_tree.h:1863
#4 0x0000000000400d79 in std::set<T*, std::less<T*>, std::allocator<T*> >::insert (this=0x6031e0 <T::Instances>, [email protected]: 0x6031d1 <d>)
at /usr/include/c++/5.3.1/bits/stl_set.h:485
#5 0x0000000000400d47 in T::T (this=0x6031d1 <d>) at common.hh:6
#6 0x0000000000400ce0 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at d.cc:2
#7 0x0000000000400d0a in _GLOBAL__sub_I_d() at d.cc:2
#8 0x0000000000401b2d in __libc_csu_init()
#9 0x00007ffff71a050f in __libc_start_main (main=0x40173b <main()>, argc=1, argv=0x7fffffffdf68, init=0x401ae0 <__libc_csu_init>, fini=<optimized out>,
rtld_fini=<optimized out>, stack_end=0x7fffffffdf58) at libc-start.c:245
#10 0x0000000000400bc9 in _start()
その何か私がしようとしてM:以下のバックトレースして、私はワンセグ障害を取得するコマンドを実行している
g++ -c -g -Wall -Wextra d.cc -o d.o
g++ -c -g -Wall -Wextra main.cc -o main.o
g++ -g d.o main.o -o app
./app
理解する。
From g++ -g d.o main.o -o app
To g++ -g main.o d.o -o app
プログラムはワンセグ障害なしで実行: 2つ目は、私がリンク順序を逆ならばということです。
$ g++ -c -g -Wall -Wextra d.cc -o d.o
$ g++ -c -g -Wall -Wextra main.cc -o main.o
$ g++ -g main.o d.o -o app
$ ./app
T::Instances.size() = 1
これはどのような働きがありますか?この問題はグローバル変数の初期化に関連しているようですが、何が起きているのかまだ分かりません。
使用G ++(GCC)5.3.1
BR、
...........................
Quentinのコメントに答えて: はい私は、静的な初期化に関連するはずですが、まだ私は実際にどのように起こっているのか分かりません。 (私はhttps://isocpp.org/wiki/faq/ctors#static-init-orderの場合、コンパイルユニットが、少なくとも直接的には別のコンパイルユニットで見つかった初期化されていないオブジェクトを呼び出しています)。私もTを追加することができます
がmain.ccファイルオブジェクト:私はまだクラッシュを得るでしょ
#include <iostream>
/*static*/ std::set<T*> T::Instances;
+T main_obj(__FILE__);
int main() {
std::cout << "T::Instances.size() = " << T::Instances.size() << std::endl;
を、ここでの私の理解では、我々は我々がすでに持っているオブジェクトの静的関数を呼び出しているということです現在のコンパイル単位(正しく初期化する必要があります)。したがって、少なくともd.ccファイルにあるオブジェクトには直接依存していません。 もう一度私は静的な初期化に関連していると強く信じていますが、私はそれの説明をはっきりと見ていません。 (私たちはその静的メンバを呼び出すオブジェクトが既に初期化されなければならない)
[Static Initialization Order Fiasco](https://isocpp.org/wiki/faq/ctors#static-init-order)に噛まれました。 – Quentin