Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Собственный обработчик исключений (ошибок), В случае глюка, надо вывести инфу 
V
    Опции темы
ksili
Дата 16.7.2007, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Вот у Виндовоза в случае ошибки приложения выскакивает сообщение со словами "Приложение совершило недопустимую ошибку...". И там есть кнопки кажись Завершить, Подробнее, Отладка. И вот если щёлкнуть по кнопке "Подробнее", то можно просмотреть содержимое регистров процессора и стека. 

Это сообщение, если не ошибаюсь выводит обработчик Винды, установленный по-умолчанию для всех приложений. Но ведь наверняка можно для своего приложения установить свой такой обработчик. Как это сделать? Пишу на BCB6


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
ksili
Дата 16.7.2007, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Приложение большое, несколько юнитов, несколько потоков. Везде блоки try... catch. замучаюсь ставить, поэтому хотелось бы такой глобальный обработчик. Фатальную ошибку отловить не могу.


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
ilyalyu
Дата 16.7.2007, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 25.10.2006

Репутация: нет
Всего: нет



В TApplication можно обрабатывать событие OnException

Добавляешь в главной форме обработчик:

procedure TForm1.OnException(Sender: TObject; e: Exception);

а потом присваиваешь его вот так:

Application.OnException  := Form1.OnException; 

На c++, думаю, сможешь переписать 

Это сообщение отредактировал(а) ilyalyu - 16.7.2007, 09:54
PM MAIL   Вверх
ksili
Дата 16.7.2007, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



А оно точно отрабатывается, когда приложение совершает недопустимую операцию и его убивает Windows?


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
ilyalyu
Дата 16.7.2007, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 25.10.2006

Репутация: нет
Всего: нет



Вот чего не знаю, того не знаю.
PM MAIL   Вверх
ksili
Дата 16.7.2007, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Цитата(ilyalyu @  16.7.2007,  14:52 Найти цитируемый пост)
Application.OnException  := Form1.OnException; 

Ну у формы я не нашёл события OnException. Но сейчас не в этом проблема. Просто создаю свою функцию и пытаюсь её назначить в качестве обработчика события Application->OnException. И что-то Билдер ругается на аргументы функции.
Моя функция:
Код

void __fastcall OnGlobalError(TObject *Sender)
{
...
}

В конструкторе формы пишу:
Код

Application->OnException = (TNotifyEvent)&OnGlobalError;

и вот именно на этой строке возникает такая мудрёная ошибка:
Код

Cannot cast from 'void (__fastcall *)(TObject *)' to 'void (__fastcall * (__closure)(TObject *))(TObject *)'

Что надо поправить в объявлении функции или назначении обработчика события? 

Это сообщение отредактировал(а) ksili - 16.7.2007, 12:26


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
ksili
Дата 16.7.2007, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Посмотрел в хелпе и сделал так:
Объявление функции:
Код

void __fastcall TForm1::OnGlobalError(TObject *Sender, Exception *E)
{
....
}

Назначение обработчика:
Код

Application->OnException = OnGlobalError;

Плюс ко всему сделал OnGlobalError членом класса формы


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
ilyalyu
Дата 18.7.2007, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 25.10.2006

Репутация: нет
Всего: нет



ksili,

"Ну у формы я не нашёл события OnException"

А там и нет такого события. Тебе надо в TForm1 определить функцию, которая будте обрабатывать событие OnException. Можешь назвать ее, например, MyOnException. Делается это примерно так (привожу пример на паскале):

Код

type TForm1 = class
  procedure MyOnException(Sender: TObject; ...);
end;


А затем присваиваешь событию OnException ссылку на эту функцию. Это выглядит примерно так:

Код

Application.OnException  := TForm1.OnException;


"и вот именно на этой строке возникает такая мудрёная ошибка:"

Мудренная ошибка возникает скорей всего потому, что ты пытаешья присвоить событию OnException адрес функции, которая не является методом класса (потому я и пишу, что функцию надо определить внутри класса TForm1). А может просто не хватает оператора "&".

Это сообщение отредактировал(а) ilyalyu - 18.7.2007, 18:10
PM MAIL   Вверх
ksili
Дата 19.7.2007, 04:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Да я уже всё так и сделал, о чём и написано в предыдущем посте. Обработчик работает, но вот сомневаюсь я, что он сработает, когда приложение совершило недопустимую операцию и будет закрыто


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
ilyalyu
Дата 19.7.2007, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 25.10.2006

Репутация: нет
Всего: нет



а ты попробуй. добавь где-нибудь деление на ноль, например, и посмотри.
PM MAIL   Вверх
ksili
Дата 20.7.2007, 04:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



я просто генерировал исключение так:
Код

throw 1;

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



--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
HappyLife
Дата 20.7.2007, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 642
Регистрация: 17.5.2006

Репутация: 4
Всего: 8



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

Добавлено через 8 минут и 56 секунд
Я думаю, что в приложениях Бильдера так не сделать.
Возьми к примеру обыкновенный Code::Blocks. Выполни операцию деления на нуль, и приложение вызовет эту ошибку.

Добавлено через 9 минут и 18 секунд
А так в любом случае, приложение завершается при срабатывании исключения.
PM MAIL   Вверх
Lazin
Дата 20.7.2007, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Вообще билдер обрабатывает исключения (необработанные) с помощю try блока в main ф-ии проекта, поэтому генерация исключения не должна приводить к завершению работы программы.
Код

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    try
    {
        Application->Initialize();
        Application->CreateForm(__classid(TMainForm), &MainForm);
        Application->CreateForm(__classid(TAboutBox), &AboutBox);
        Application->Run();
    }
    catch (Exception &exception)
    {
        Application->ShowException(&exception);
    }
    catch (...)
    {
        try
        {
            throw Exception("");
        }
        catch (Exception &exception)
        {
            Application->ShowException(&exception);
        }
    }
    return 0;
}

Так-что можно это под свои нужды переделать, например в лог писать или баг репорт посылать. Я однажды видел прогу, которая перед смертью открывала свой лог блокнотом, а в логе - предложение отправить этот файл авторам. Мне сразу такое захотелось туда написать smile 
ЗЫ
Если прога многопоточная, то нужно в каждом потоке отдельно исключения обрабатывать.
PM MAIL Skype GTalk   Вверх
ksili
Дата 24.7.2007, 06:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Точно, про юнит проекта я и забыл. А в каком из этих трёх catch'ей лучше вставить свой код? Мне как раз в лог и надо писать.
Про потоки тоже учту


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Lazin
Дата 24.7.2007, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Цитата

А в каком из этих трёх catch'ей лучше вставить свой код? 

Наверное можно и свой добавить:
Код

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    try
    {
        Application->Initialize();
        Application->CreateForm(__classid(TMainForm), &MainForm);
        Application->CreateForm(__classid(TAboutBox), &AboutBox);
        Application->Run();
    }
    catch (const myException &_exc)//своё исключение
    {    Log::process_exception (_exc);
    }
    catch (Exception &exception)//исключения VCL
    {
        Application->ShowException(&exception);
    }
    catch (...)//неизвестное исключение
    {
        try
        {
            throw Exception("");
        }
        catch (Exception &exception)
        {
            Application->ShowException(&exception);
        }
    }
    return 0;
}

Вообще исключения желательно не только в лог писать, но и пытаться их обработать как можно ближе к месту возникновения, для того чтобы можно было восстановить нормальный ход работы программы.
PM MAIL Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0555 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.