2014-09-04 3 views
0

Я хотел бы знать, существует ли какой-либо тривиальный способ уничтожить объект, который был создан в main() после того, как приложение просто разбилось (или было прервано или каким-то другим). код:Как уничтожить объект, созданный в main() после SIGSEGV

#include <iostream> 
#include <signal.h> 
#include <stdlib.h> 

class TestClass { 
public: 
    TestClass() { std::cerr << "Constructor" << std::endl; } 
    ~TestClass() { std::cerr << "Destructor" << std::endl; } 
}; 

void signal_handler(int signum) { 
    std::cerr << "Signal caught " << signum << std::endl; 
    exit(1); 
} 

int main() { 

    TestClass a; 

    struct sigaction new_action, old_action; 
    new_action.sa_handler = signal_handler; 
    sigemptyset (&new_action.sa_mask); 
    new_action.sa_flags = 0; 

    sigaction (SIGSEGV, NULL, &old_action); 
    if (old_action.sa_handler != SIG_IGN) 
    { 
     sigaction (SIGSEGV, &new_action, NULL); 
    } 
    // CRASH !!! 
    int* p = 0; *p = 0; 
} 

таким образом, установить обработчик сигнала, который после выполнения должен сделать некоторые очистки, и только после этого выхода Очевидно, что это большое приложение, поэтому я хотел бы, чтобы вызвать деструктор моих классов. которые создавали временные файлы (теоретически).

Было бы легко выделить его динамически и в signal_handler просто освободите его (чтобы вызвать деструктор), но это требует некоторой дополнительной работы.

А также, это может быть глобальным объектом, но я хочу, чтобы избежать глобальной проблемы порядка инициализации ...

+1

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

+3

@JoachimPileborg: вы правы, что операционная система освободит память, файлы, сетевые подключения и некоторые другие ресурсы. Но он не освободит все, например. временные файлы, очереди сообщений POSIX, и я уверен, что у многих есть много «унаследованных» ресурсов, которых нет, скажем так, «ориентированных на соединение». Вот популярный вопрос, который я задал давно в одном из таких случаев: http://stackoverflow.com/questions/471344/guaranteed-file-deletion-upon-program-termination-cc –

+0

@fritzone: это ваше приложение, подобное серверу, с центральный цикл событий проходит круглый и круглый? Или это скорее процедура, одноразовое приложение? –

ответ

1

Вы могли бы попытаться организовать упорядоченное выключение по SIGSEGV. Это не без его подводных камней, но начинайте здесь: Is it possible to terminate only the one thread on receiving a SIGSEGV?

Вы можете попытаться прервать одну оскорбительную нить в вашем обработчике сигнала и установить глобальный флаг, чтобы сказать: «Мы ввернуты, время для закрытия». Затем в вашем основном цикле сообщения проверьте флаг и выйдите, если он установлен.