2013-09-30 29 views
0

將字符串寫入ostream對象時,我的Linux C++應用程序崩潰。 我的原始應用程序試圖創建一個非常bigg的字符串輸出並將所有字符串輸出寫入一個流。在將字符串寫入ostream對象時,應用程序崩潰。起初,崩潰發生在Windows和Linux。如何在linux上捕獲ostream異常?

現在該問題在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的輸出:

[[email protected] streamError]$ ./a.out 
Segmentation fault (core dumped) 
[[email protected] 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(64位)的gcc版本4.4.7 編譯參數。 $ g ++ overflow.cxx -g3 -m64 -O0 -ggdb

在Windows中它正在退出,但是在Linux中,這會因分段錯誤錯誤而崩潰。 我正在尋找的是我的應用程序應該乾淨的退出。我不希望它退出分段錯誤錯誤。

我不知道如何在Linux下處理這個問題,任何人都可以指導我。

+0

嘗試另一個編譯器並擺脫auto_ptr。這與現代編譯器一起工作:http:// ideone。com/42bhEJ(我剛剛複製粘貼你的代碼)。 – stefan

+0

'strstream'已過時,絕對不能使用。標準頭被稱爲'sstream'。 –

+0

ostrstream現在已被棄用,我必須使用** ostringstream **。應用ostringstream之後,程序會拋出期望的bad_alloc並乾淨地退出。(特別感謝Alan,Lance和@DavidNorman :))。 – thanga

回答

1

這似乎是與您的Linux上的副本gcc標準庫航運問題。 更新您的編譯器(4.8.1是當前版本的gcc,截至2013年9月30日),您將獲得預期行爲,如您在此demo中所見。

附註:auto_ptr不應再使用。使用unique_ptrshared_ptr。在這種情況下,既不需要,也可以刪除new

+0

目前我無法在開發環境中使用4.8.1編譯器。但我已經開始在代碼中使用** ostringstream **。現在程序拋出異常並正常退出。 – thanga