0

在下面的代码中,我try/catch在 python 模块代码中使用。在该try块中,我有一个简单的错误(内存访问冲突)并试图捕获相应的异常并在不生成.stackdump文件的情况下安静地终止程序。然而,后者仍然生成,这意味着try/catch构造没有完成它的工作。.stackdump当遇到不正确的操作(如代码中的操作)时,如何避免生成文件并退出程序而不会出错?PS我正在用gcc和boost.python在cygwin中编译代码

有趣的是,它不仅适用于 case x[3]=2,而且适用于所有其他情况:例如x[4]=2or x[20]=2or ,显然,x[2]=2

#include <boost/python.hpp>
#include <iostream>
#include <iomanip>
using namespace std;
using namespace boost::python;


class Hello
{
    std::string _msg;

public:

    Hello(std::string msg){_msg = msg;}

    void run(){
      try{  

        double* x;
        x = new double[3];
        x[3] = 2.0;
        delete [] x;


      }catch(...){  exit(0);   }

    }

};


BOOST_PYTHON_MODULE(xyz)
{
    class_<Hello>("Hello", init<std::string>())
        .def("run",&Hello::run)
    ;  

}

编辑:

根据 Maciek 的建议,我尝试了以下技巧:

使信号处理函数抛出异常,但不退出

void sig_action(int signo) {
    std::cout << "SIGNAL " << signo << std::endl;
    throw 1;
//    exit(0);
}

现在尝试在 try/catch 块中包含一个可能有问题的函数(信号函数放在类构造函数中):

class Hello
{
    std::string _msg;

public:

    Hello(std::string msg){
    _msg = msg;
      signal(SIGABRT, sig_action);
      signal(SIGSEGV, sig_action);

    }
    void set(std::string msg) { this->_msg = msg; }
    std::string greet() { return _msg; }

    void run(){

      try{  
        double* x;
        x = new double[3];
        x[3] = 2.0;
        delete [] x;

      }catch(...){ cout<<"error in function run()\n"; exit(0);   }

    }

};

然而,这样的技巧并没有像我预期的那样起作用,它会产生以下输出:

SIGNAL 6
terminate called after throwing an instance of 'int'
SIGNAL 6
terminate called recursively
SIGNAL 6
terminate called recursively
....
(and many more times the same)

所以抛出异常,但一切都在它被捕获之前完成。有没有办法在终止进程之前让它被捕获?

4

2 回答 2

1

在 linux 上,核心转储由信号处理程序生成,默认操作设置为core( SIGABRT, SIGSEGV, ...)。如果您想避免核心转储,您可以随时捕获/忽略这些信号。它也应该适用于 Cygwin stackdumps。但是您仍然可能会收到一些讨厌的消息作为输出。

编辑:

#include <signal.h>

// [...]

void sig_action(int signo) {
    std::cout << "SIGNAL " << signo << std::endl;
    exit(0);
}

int main(int argc, char* argv[]) {
    signal(SIGABRT, sig_action);
    signal(SIGSEGV, sig_action);

    Hello h("msg");
    h.run();
}
于 2013-03-24T22:32:08.227 回答
1

您只能捕获抛出的异常。无效的指针访问不会引发异常,它只会导致未定义的行为,并且在您的特定情况下会导致堆栈转储。

如果你想捕捉这种情况的情况,使用std::vectorat功能来访问项目。std::out_of_range这将在与无效索引一起使用时抛出。但是,通常最好先避免此类访问的可能性,因为它们通常表明程序中存在错误,并且错误不应通过异常处理,应从代码中删除。

于 2013-03-24T20:55:42.660 回答