попробуйте / поймать, чтобы избежать .stackdump

В приведенном ниже коде я использую try/catch в коде модуля Python. в try Блок у меня есть простая ошибка (нарушение доступа к памяти) и пытается перехватить соответствующее исключение и тихо завершить программу без генерации .stackdump файл. Однако последнее все еще генерируется, что подразумевает, что try/catch конструкция не делает свою работу. Как я могу избежать генерации .stackdump файл и выход из программы без ошибок, когда неправильная операция (как в коде) встречается?
Постскриптум я компилирую код в cygwin с помощью gcc и boost.python

Интересно, что это не работает только в случае 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)
;

}

РЕДАКТИРОВАТЬ:

В соответствии с тем, что Мацек предложил, я попробовал следующий трюк:

Сделайте функцию обработки сигналов для выдачи исключения, но не выхода

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)

Таким образом, исключение выдается, но все заканчивается до того, как его поймают. Есть ли способ, чтобы он был пойман до завершения процесса?

0

Решение

Вы можете ловить только те исключения, которые выбрасываются. Недопустимый доступ к указателю не вызывает исключение, он просто вызывает неопределенное поведение, а в вашем конкретном случае это приводит к сбросу стека.

Если вы хотите уловить такую ​​ситуацию, используйте std::vector и at функция чтобы получить доступ к элементам. Это бросит std::out_of_range при использовании с неверным индексом. Однако, как правило, лучше избегать возможности такого доступа априори, поскольку они обычно указывают на ошибку в вашей программе, и ошибки не должны обрабатываться с помощью исключений, их следует удалять из кода.

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();
}
1

По вопросам рекламы [email protected]