Linux カーネル 3.6.6-1、gcc 4.7.2-2、次のプログラムを実行します。
1 #include <vector>
2 using namespace std;
3 int main ()
4 {
5 vector<size_t> a (1 << 24);
6 return 0;
7 }
5 行目から戻ることはありません。
gdb で実行すると、stl_algobase.h の 743/744 行目でスタックしていることがわかります。
0x000000000040101c in std::__fill_n_a<unsigned long*, unsigned long, unsigned long> (__first=0x7fffeffd8060, __n=16777216, __value=@0x7fffffffe0a8: 0)
at /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_algobase.h:743
740 __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
741 {
742 const _Tp __tmp = __value;
743 for (__decltype(__n + 0) __niter = __n;
744 __niter > 0; --__niter, ++__first)
745 *__first = __tmp;
746 return __first;
747 }
__niter は値 1 にとどまり、0 までカウントダウンすることはありません。
この動作は、システムをしばらく実行した後にのみ発生します。そして、それが発生すると、システム全体が機能不全に陥ったように見えます。つまり、GUI はすぐに応答を停止しますが、ssh に接続していくつかのことを行うことはできますが、最終的にシステム全体が使用できなくなり、再起動します。
再起動後、上記のプログラムは期待どおりに動作します。
明らかに、問題は私のプログラムにはありません。それは、より大きな問題の兆候にすぎません。
私の質問は次のとおりです。次に何をしますか?
すべてのエラー ログを確認しましたが、何も見つかりませんでした。ハードウェアの例外などは発生していないため、システムがいつこの状態になるかを正確に判断するのは困難です。
私はアイデアが不足しているので、どんな助けでも大歓迎です。
編集:
コンパイラ オプションを に変更し-g -Wall
たところ、同じ結果が得られました。
__fill_n_a の逆アセンブリを次に示します (新しいオプションを使用)。
1 0x00000000004010bd <+0>: push %rbp
2 0x00000000004010be <+1>: mov %rsp,%rbp
3 0x00000000004010c1 <+4>: mov %rdi,-0x18(%rbp)
4 0x00000000004010c5 <+8>: mov %rsi,-0x20(%rbp)
5 0x00000000004010c9 <+12>: mov %rdx,-0x28(%rbp)
6 0x00000000004010cd <+16>: mov -0x28(%rbp),%rax
7 0x00000000004010d1 <+20>: mov (%rax),%rax
8 0x00000000004010d4 <+23>: mov %rax,-0x10(%rbp)
9 0x00000000004010d8 <+27>: mov -0x20(%rbp),%rax
10 0x00000000004010dc <+31>: mov %rax,-0x8(%rbp)
11 0x00000000004010e0 <+35>: jmp 0x4010f7 <std::__fill_n_a<unsigned long*, unsigned long, unsigned long>(unsigned long*, unsigned long, unsigned long const&)+58>
12 0x00000000004010e2 <+37>: mov -0x18(%rbp),%rax
13 0x00000000004010e6 <+41>: mov -0x10(%rbp),%rdx
14 0x00000000004010ea <+45>: mov %rdx,(%rax)
15 0x00000000004010ed <+48>: subq $0x1,-0x8(%rbp)
16 0x00000000004010f2 <+53>: addq $0x8,-0x18(%rbp)
17 0x00000000004010f7 <+58>: cmpq $0x0,-0x8(%rbp)
18 0x00000000004010fc <+63>: setne %al
19 0x00000000004010ff <+66>: test %al,%al
20 0x0000000000401101 <+68>: jne 0x4010e2 <std::__fill_n_a<unsigned long*, unsigned long, unsigned long>(unsigned long*, unsigned long, unsigned long const&)+37>
21 0x0000000000401103 <+70>: mov -0x18(%rbp),%rax
22 0x0000000000401107 <+74>: pop %rbp
23 0x0000000000401108 <+75>: retq
また、システムのメモリ診断ツールをエラーなしで実行しました。また、DL が示唆するように、memtest86 をエラーなしで実行しました。
編集:
別のマシンで同じコードを実行して、これがハードウェアの問題ではないことを確認しました。もう一方のマシンには同じカーネルとコンパイラ ソフトウェアがインストールされており、同じように失敗します。
私は ImageMagick を疑っています。これは、多くの ImageMagick 変換呼び出しを行うスクリプトを実行した後にのみ発生するようです。以前に ImageMagick に問題があり、シェル変数 MAGICK_THREAD_LIMIT=1 を設定する必要がありました。