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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Перехват qFatal  (Прочитано 5518 раз)
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« : Май 14, 2012, 15:26 »

Qt 4.8.1, Windows
Перехватываю вывод qDebug и т.п. через qInstallMsgHandler. При этом я ожидаю следующего поведения: пусть где-то внутри кода срабатывает qFatal("error"). Вызывается мой собственный обработчик ошибок, я шлю сообщение главному окну, что "всё плохо", вывожу в лог причину ошибки и корректно завершаю программу. Однако, получаю не совсем то, чего ожидаю - на экран всё равно вылезает окно типа "abnormal program termination". Лезу в qt_message_output и вижу следующее:
Код
C++ (Qt)
void qt_message_output(QtMsgType msgType, const char *buf)
{
   if (handler) {
       (*handler)(msgType, buf);   // Тут будет вызван мой обработчик
   }
...
   if (msgType == QtFatalMsg
       || (msgType == QtWarningMsg
           && (!qgetenv("QT_FATAL_WARNINGS").isNull())) ) {
...
#elif (defined(Q_OS_UNIX) || defined(Q_CC_MINGW))
       abort(); // trap; generates core dump
#else
       exit(1); // goodbye cruel world
#endif
   }
}
 

То есть, qFatal вне зависимости от моих пожеланий в его обработчике абортит приложение. В чём же тогда смысл его перехвата и что мне с этим делать?
Записан
mutineer
Гость
« Ответ #1 : Май 14, 2012, 15:29 »

Смысл его перехвата в выводе креш-сообщения не в консоль
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #2 : Май 14, 2012, 15:34 »

Дак не даёт оно мне вывести его. В перехватчике генерю событие и отправляю его своей системе логирования. Но пока идёт раскрутка цикла обработки сообщений приложение уже шандарахнулось по abort(). В итоге сообщения об ошибке нет уже нигде.
Записан
Akon
Гость
« Ответ #3 : Май 14, 2012, 15:42 »

Цитировать
... Вызывается мой собственный обработчик ошибок, я шлю сообщение главному окну, что "всё плохо", вывожу в лог причину ошибки и корректно завершаю программу
С чего вы взяли, что удастся корректно завершить программу?

Цитировать
Дак не даёт оно мне вывести его. В перехватчике генерю событие и отправляю его своей системе логирования. Но пока идёт раскрутка цикла обработки сообщений приложение уже шандарахнулось по abort(). В итоге сообщения об ошибке нет уже нигде.
Что это за логирование ошибок, которое зависит от компонентов, в которых эти ошибки и могут произойти?

Ну вот, например
Код:
QObjectPrivate::QObjectPrivate(int version)
    : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0)
{
    if (version != QObjectPrivateVersion)
        qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
                version, QObjectPrivateVersion);

    // QObjectData initialization
    q_ptr = 0;
    parent = 0;                                 // no parent yet. It is set by setParent()
    isWidget = false;                           // assume not a widget object
    pendTimer = false;                          // no timers yet
    blockSig = false;                           // not blocking signals
    wasDeleted = false;                         // double-delete catcher
    sendChildEvents = true;                     // if we should send ChildInsert and ChildRemove events to parent
    receiveChildEvents = true;
    postedEvents = 0;
    extraData = 0;
    connectedSignals[0] = connectedSignals[1] = 0;
    inThreadChangeEvent = false;
#ifdef QT_JAMBI_BUILD
    inEventHandler = false;
    deleteWatch = 0;
#endif
    metaObject = 0;
    hasGuards = false;
}
А вы хотите цикл обработки сообщений.
« Последнее редактирование: Май 14, 2012, 15:46 от Akon » Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #4 : Май 14, 2012, 15:53 »

С чего вы взяли, что удастся корректно завершить программу?
Понятно, что это сильно будет зависеть от рода ошибки. Но ведь раз уж я устанавливаю собственный обработчик ошибок и библиотека вроде-бы предоставляет мне соответствующий инструментарий - может всё-таки лучше мне решать, что делать в случае фатальной ошибки?

Цитировать
Что это за логирование ошибок, которое зависит от компонентов, в которых эти ошибки и могут произойти?
Не понял о чём тут. Любая система неизбежно будет зависеть от тех компонент, на которых она написана.
Записан
Akon
Гость
« Ответ #5 : Май 14, 2012, 16:06 »

Цитировать
Понятно, что это сильно будет зависеть от рода ошибки. Но ведь раз уж я устанавливаю собственный обработчик ошибок и библиотека вроде-бы предоставляет мне соответствующий инструментарий - может всё-таки лучше мне решать, что делать в случае фатальной ошибки?
Это зависит не от рода ошибки, а от смысла, заложенного разработчиком (троллями): qFatal - не подразумевает корректного завершения программы.

Цитировать
Не понял о чём тут. Любая система неизбежно будет зависеть от тех компонент, на которых она написана.
Например, синхронный вывод сообщения в консоль или сброс сообщения в лог-файл никак не зависят от работы цикла сообщений.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 14, 2012, 16:07 »

Не понял о чём тут. Любая система неизбежно будет зависеть от тех компонент, на которых она написана.
Диагностика должна быть независимой. Напр перехватив обработчик Вы сможете записать ошибку в файл - если будете пользоваться напр системными ф-циями записи и вызывать их тут же. Но если логирование требует механизма событий  (который уже приказал долго жить) - записать вряд ли удастся
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #7 : Май 14, 2012, 16:19 »

Например, синхронный вывод сообщения в консоль или сброс сообщения в лог-файл никак не зависят от работы цикла сообщений.
Ну да. Только вот они зависят от работоспособности файловой и дисковой подсистем.

Но если логирование требует механизма событий  (который уже приказал долго жить) - записать вряд ли удастся
Ну тут можно продолжать бесконечно - а если логирование требует записи в файл, а сломался именно жесткий диск - что тогда? Или уж совсем экстремально - а если логирование выводит ошибки на экран, а сломался видеоадаптер - как об этом сообщить пользователю? Все эти моменты прекрасно мне понятны - ограничимся собственно исходным вопросом: зачем давать пользователю устанавливать собственный обработчик ошибок и тем не менее решать за него как эти ошибки обрабатывать?
« Последнее редактирование: Май 14, 2012, 16:48 от xokc » Записан
Akon
Гость
« Ответ #8 : Май 14, 2012, 16:50 »

Смысл перехвата в возможности сделать еще что либо специфичное. Но эта специфичная обработка не должна быть связана с функциями приложения. Оно должно умереть по замыслу разработчика (троллей). Цикл обработки сообщений - это функция приложения.
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #9 : Май 14, 2012, 17:39 »

Я Ваше мнение понял, хотя с ним и не согласен. Дискуссию при этом полагаю для себя закрытой.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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