抛出“std::string”实例后调用终止

Tur*_*rbo 2 c++ exception-handling stack-trace

我有这个二进制文件通过抛出 std:string 类型的异常而崩溃。

来自剥离二进制文件的堆栈跟踪:

terminate called after throwing an instance of 'std::string'
*** Aborted at 1309483487 (unix time) try "date -d @1309483487" if you are using GNU date ***
PC: @       0x3fb0c30155 (unknown)
*** SIGABRT (@0xd54) received by PID 3412 (TID 0x40d03940) from PID 3412; stack trace: ***
    @       0x3fb180de70 (unknown)
    @       0x3fb0c30155 (unknown)
    @       0x3fb0c31bf0 (unknown)
    @     0x2aaaaab80cc4 (unknown)
    @     0x2aaaaab7ee36 (unknown)
    @     0x2aaaaab7ee63 (unknown)
    @     0x2aaaaab7ef4a (unknown)
    @           0x4c2622 XYZ::connect()
    @           0x4c3e0f XYZ::refresh()
    @       0x3fb18062f7 (unknown)
    @       0x3fb0cd1e3d (unknown)
Run Code Online (Sandbox Code Playgroud)

现在的问题是,refresh() 函数确实尝试捕获 std::string。看起来像:-

bool XYZ::refresh() {
  try {
    connect();
  } catch (string& s) {
    return false;
  }
  return true;
}
Run Code Online (Sandbox Code Playgroud)

知道为什么它没有被抓住吗?或者我读错了堆栈跟踪?

Mic*_*urr 5

也许部分或所有模块是用-fno-exceptions? 有关如何更改异常行为的详细信息,请参阅http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html

例如,以下短程序在以下情况下显示"terminate called after throwing an instance of 'std::string'"

  • 包含的模块foo()是用-fno-exceptions, 和
  • foo()调用抛出类型异常的东西std::string(所有其他模块都是用 编译的-fexceptions

    #include <string>
    #include <iostream>
    
    using namespace std;
    
    int foo();
    
    int main()
    {
        try {
            foo();
        }
        catch (string& s) {
            std::cout << "caught it: \"" << s << "\"" << endl;
        }
    
        return 0;
    }
    
    Run Code Online (Sandbox Code Playgroud)

请注意,如果我简单地foo.cpp使用 -fexceptions(g++ 的默认值)重新编译并重新链接,程序将显示:

caught it: "the string exception"
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。


或者也许某些中间函数有一个没有列出的 throw 规范std::string

例如,这个程序:

#include <string>
#include <iostream>

using namespace std;

int Hunc() throw(int); // can only throw int (?)

int main()
{
    try {
        Hunc();
    }
    catch (string& s) {
        std::cout << "caught it: \"" << s << "\"" << endl;
    }

    return 0;
}


int Hunc() throw(int)
{
    throw string("the string exception");
}
Run Code Online (Sandbox Code Playgroud)

还显示“在抛出 'std::string' 实例后调用终止”。这两个示例都在装有 MinGW 4.5.1 的 Windows 机器上进行了测试。