Russian Qt Forum
Ноябрь 23, 2024, 00:51 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: А есть ли смысл??? SIGSEGV SIGFPE и т.д.  (Прочитано 6926 раз)
west
Гость
« : Июнь 29, 2006, 15:16 »

Простите меня неуча, но никак не могу разобраться с сигналами в UNIX OC. Дело в том, что максимум чего полезного могу получить от них, так это квитанцию о смерте проги за один шаг до оной. Перехват сигналов понятен, но как вернуться в точку ошибки (а еще лучше за шаг до нее!), раскрутить стек и выполнить обходной маневр, не залазя в критическую секцию. Все что касается блоков  try catch не очень подходит, т.к. это исключительные ситуации языка, т.е. new [-2] оно поймает, а 10/0 - нет. Неужели никто не сталкивался с такой проблемой, и не пытался обработь искл. ситуацию через сигналы? Ведь они похоже и сделаны для этого. Прокатил у меня правда вариант с функциями setjmp() и longjmp(), но он удобен только для однопоточного приложения. Да, кстати, о задачи. Пускаю н-ое количество мат. расчетов в so-шках, библиотеки не мои, каждый раз разные. Для каждой организую свой поток. Попадется корявая, может зависнуть до ста пользователей, будут ждать, пока сервер перегрузится. И не могу я для каждой библы использовать свое адресное пространство! Умрет система при обмене данных. Хотя, наверное , это уже вопрос отдельного топика.
Резюме задачи (простите еще раз за эмоции, которые были выше), работает серверное приложение, у которого порядка 250 математических библиотек, состав которых меняется. Клиенты цепляются на сервер, по сети вливают свои данные и начинают применять к ним всю подряд математику. Из-за недопонимания процесса частенько используют не то или не к тому, что, собственно и ведет к завалу комплекса в целом. Как сделать так, чтобы если мат.библ. споткнулась на вычислениях, это не приводило к завершению работы сервера. Пока о том, что что-то где-то не так я узнаю  только по сигналам.
Записан
yurror
Гость
« Ответ #1 : Февраль 16, 2007, 12:34 »

SIGSEGV ловить? хм...
на freebsd был примерчик...

Код:

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

class e_access_violation
{
        public:
                e_access_violation() {};
};

void segv_handler(int sig)
{
        throw e_access_violation();
}

int main()
{
        signal(SIGSEGV, segv_handler);
        try
        {
                *((char *)0) = 0;
        }
        catch (e_access_violation)
        {
                std::cout << "Access Violation" << std::endl;
        }
        std::cout << "I'm live!" << std::endl;
        return 0;
}


Код:

yurik@vpn ~$ g++ except.cpp
yurik@vpn ~$ ./a.out
Access Violation
I'm live!


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

добавлено спустя 2 часа 16 минут:

 Для Linux получилось только так... изврат дикий...
try.h
Код:

#ifndef TRY_H
#define TRY_H

#include <setjmp.h>
#include <csignal>

void setup_signals(void);

#ifndef IN_TRY_CC
extern
#endif
        sigjmp_buf buf;

#define __try \
        setup_signals(); \
        int direct_ret = sigsetjmp(buf, 1); \
        if (direct_ret) \


#define __except else

#define __finally

#endif /* TRY_H */


try.cc
Код:

#define IN_TRY_CC
#include "try.h"

void setup_signals(void)
{
        std::signal(SIGHUP, signals_handler);
        std::signal(SIGINT, signals_handler);
        std::signal(SIGILL, signals_handler);
        std::signal(SIGBUS, signals_handler);
        std::signal(SIGFPE, signals_handler);
        std::signal(SIGSEGV, signals_handler);
}

void unset_signals(void)
{
        std::signal(SIGHUP, SIG_DFL);
        std::signal(SIGINT, SIG_DFL);
        std::signal(SIGILL, SIG_DFL);
        std::signal(SIGBUS, SIG_DFL);
        std::signal(SIGFPE, SIG_DFL);
        std::signal(SIGSEGV, SIG_DFL);
}

void signals_handler(int signo)
{
        unset_signals();
        siglongjmp(buf, 1);
}


sample.cc
Код:
#include <iostream>
#include "try.h"
int main()
{
        __try
        {
                *((char *)0) = 0;
        }
        __except
        {
                std::cout << "Access Violation" << std::endl;
        }
        std::cout << "I'm live!" << std::endl;
        // а вот после этой строчки приложение реально "свалится"
        *((char *)0) = 0;
        // и никакого возврата нуля не будет
        return 0;
}


добавлено спустя 2 минуты:

 
Код:

yurik@vox:~/work/exceptions$ ./a.out
Access Violation
I'm live!
Segmentation fault
Записан
yurror
Гость
« Ответ #2 : Март 02, 2007, 04:02 »

Сегодня заупустил программульку в Wine а она возьми да и выдай окошко Access Violation тост-боси... так что это 1) возможно 2) сделано. Надо будет расковырять исходники wine.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.123 секунд. Запросов: 20.