0

我的 Linux C++ 应用程序在将字符串写入 ostream 对象时崩溃。我的原始应用程序尝试创建一个非常大的字符串输出并将所有字符串输出写入一个流。在将字符串写入 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

版本和编译器详细信息。

视窗 2008 (64 位) - VS2008

rhel62(64bit) gcc 版本 4.4.7 编译参数。$g++ 溢出.cxx -g3 -m64 -O0 -ggdb

在 Windows 中,它可以正常退出,但在 Linux 中,它会因分段错误错误而崩溃。我正在寻找的是我的应用程序应该干净退出。我不希望它以分段错误错误退出。

我不确定如何在 Linux 中处理这个问题,任何人都可以指导我。

4

1 回答 1

1

这似乎是随您的gcclinux 副本一起提供的标准库的问题。更新您的编译器(4.8.1 是 gcc 的当前版本,截至 2013 年 9 月 30 日),您将获得预期的行为,如您在此演示中所见。

旁注:auto_ptr不应再使用。使用unique_ptrshared_ptr。在这种情况下,两者都没有必要,删除new.

于 2013-09-30T16:59:15.163 回答