尝试/赶上,以避免.stackdump
在下面的代码中,我在python模块代码中使用try/catch
。在try
块中,我有一个简单的错误(内存访问冲突),并试图捕获相应的异常并安静地终止程序,而不生成.stackdump
文件。然而,后者仍然生成暗示try/catch
构造不能完成它的工作。我怎样才能避免生成.stackdump
文件并在不正确的操作(如代码中的一个)得到满足时退出程序? P.S.我正在编制在Cygwin中的代码用gcc和Boost.Python的尝试/赶上,以避免.stackdump
有趣的是,它没有的情况下,仅x[3]=2
工作,而是适用于所有其他情况:例如x[4]=2
或x[20]=2
,或者显然,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)
所以抛出异常,但它已被抓之前一切结束。有什么办法让它在终止这个过程之前被抓到?
您只能捕获抛出的异常。无效的指针访问不会引发异常,它只会导致未定义的行为,并且在您的特定情况下会导致堆栈转储。
如果您想要了解这种情况,请使用std::vector
和at
function访问项目。当与无效索引一起使用时,这将抛出std::out_of_range
。但是,通常最好先避免这种访问的可能性,因为它们通常指示程序中的错误,并且错误不应该通过例外来处理,它们应该从代码中移除。
在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();
}
不知道如何使用它。你能否提供一些细节如何在代码中包含这些内容(例如,例子中的那个)? – user938720 2013-03-24 22:45:14
我已经添加了一个示例代码。如果您只是想忽略该信号,请使用'SIG_IGL'作为动作功能 – 2013-03-24 22:56:42
谢谢Maciek。这是一般工作,但它是否有可能检查代码的哪一部分出现问题?例如,让我们说我们有另一个没有错误的函数run1(比如在原始运行中)并调用这两个函数。在信号使用的基础上,我怎么知道哪一个会导致这个问题呢?使用try/catch构造,可以将每个函数括起来并区分哪一个包含错误。是否有可能做这样的信号功能? – user938720 2013-03-24 23:12:08
谢谢。事实上,这就是我如何找到一个错误 - 通过找到引发异常的代码(很可能是内存访问的一些问题)的一部分。我知道这不是应该如何找到一个错误,但它是我目前唯一的方式 - 它的一个长长的故事。我还添加了一些更正 - 似乎仍然抛出异常,但不是所有情况下;但在其中大部分。 – user938720 2013-03-24 21:07:35