ostream オブジェクトに文字列を書き込んでいるときに Linux C++ アプリケーションがクラッシュします。私の元のアプリケーションは、非常に大きな文字列出力を作成し、すべての文字列出力をストリームに書き込もうとします。文字列を ostream オブジェクトに書き込んでいるときに、アプリケーションがクラッシュしました。最初は Windows と Linux の両方でクラッシュが発生しました。
この問題は、Windows 環境で修正されました (詳細は後述)。しかし、Linuxではクラッシュしています。
以下は、同じシナリオを生成するサンプル c++ プログラムです。
#include <iostream>
#include <strstream>
#include <memory>
using namespace std;
bool fillScreen(std::ostream&);
int main ()
{
auto_ptr<ostrstream> screen(new ostrstream);
bool succ = false;
try
{
succ = fillScreen(*screen);
}catch(std::exception &ex)
{
std::cerr << ex.what() << std::endl;
}
if(succ)
{
std::cout << "SCREEN Content is : " << screen->str() << std::endl;
}
else
{
std::cout << "NOTHING ON SCREEN Object " << std::endl;
}
}
bool fillScreen(ostream &scr)
{
unsigned long idx = 0;
scr.exceptions(std::ios::badbit);// throws exception in windows but not in Linux.
while (idx++ < 999999999)
{
scr << "BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH_" << " : " ;
scr << "BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_";
scr << "BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH_"<< std::endl;
/*if(!(idx %100000))
{
std::cout << "Reached iteration: " << idx << std::endl;
}*/
}
return true;
}
プログラムに次のステートメントを追加しました
screen.exceptions(std::ios::badbit);
このステートメントにより、私のプログラムは Windows でクラッシュしなくなりました。Windows での実行中に、ストリームが badbit 例外をスローし、アプリケーションが例外を処理して正常に終了しました。
次のように出力します。
Windows 出力: (cygwin を使用して実行)
$ ./overflow.exe
bad allocation
NOTHING ON SCREEN Object
きれいな出口。
Linux 出力:
[Mybuild@devlnx01 streamError]$ ./a.out
Segmentation fault (core dumped)
[Mybuild@devlnx01 streamError]$
クラッシュ - クリーンな終了ではありません。例外を設定しても
screen.exceptions(std::ios::badbit);
以下は、Linux gdb を使用して取得したスタック トレースです (コア ダンプ ファイルを使用)。
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 std::strstreambuf::overflow (this=0x17f8018, c=72) at ../../.././libstdc++-v3/src/strstream.cc:174
174 ../../.././libstdc++-v3/src/strstream.cc: No such file or directory.
in ../../.././libstdc++-v3/src/strstream.cc
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.x86_64
(gdb) where
#0 std::strstreambuf::overflow (this=0x17f8018, c=72) at ../../.././libstdc++-v3/src/strstream.cc:174
#1 0x00007eff6f4e7565 in std::basic_streambuf<char, std::char_traits<char> >::xsputn (this=0x17f8018, __s=<value optimized out>, __n=72)
at /export/disk1/build/GCC4.5.3/gcc-4.5.3/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/streambuf.tcc:97
#2 0x00007eff6f4ddb85 in sputn (__out=..., __s=0x401038 "BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH_", __n=72)
at /export/disk1/build/GCC4.5.3/gcc-4.5.3/x86_64-unknown-linux-gnu/libstdc++-v3/include/streambuf:429
#3 __ostream_write<char, std::char_traits<char> > (__out=...,
__s=0x401038 "BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH_", __n=72)
at /export/disk1/build/GCC4.5.3/gcc-4.5.3/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/ostream_insert.h:48
#4 std::__ostream_insert<char, std::char_traits<char> > (__out=...,
__s=0x401038 "BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH_", __n=72)
at /export/disk1/build/GCC4.5.3/gcc-4.5.3/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/ostream_insert.h:99
#5 0x00007eff6f4dde0f in std::operator<< <std::char_traits<char> > (__out=...,
__s=0x401038 "BLAHBLAHBLAH_BLAH_BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH BLAHBLAHBLAH_BLAH_")
at /export/disk1/build/GCC4.5.3/gcc-4.5.3/x86_64-unknown-linux-gnu/libstdc++-v3/include/ostream:513
#6 0x0000000000400d82 in fillScreen (scr=...) at overflow.cxx:35
#7 0x0000000000400c31 in main () at overflow.cxx:14
バージョンとコンパイラの詳細。
Windows 2008 (64 ビット) - VS2008
rhel62(64bit) gcc バージョン 4.4.7 コンパイル引数。$g++ オーバーフロー.cxx -g3 -m64 -O0 -ggdb
Windows では正常に終了しますが、Linux ではセグメンテーション違反エラーでクラッシュします。私が探しているのは、アプリケーションがクリーンな終了を行う必要があることだけです。セグメンテーション違反エラーで終了したくありません。
Linuxでこれを処理する方法がわかりません。これについて誰か教えてもらえますか。