Russian Qt Forum

Qt => Общие вопросы => Тема начата: xokc от Май 14, 2012, 15:26



Название: Перехват qFatal
Отправлено: xokc от Май 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 вне зависимости от моих пожеланий в его обработчике абортит приложение. В чём же тогда смысл его перехвата и что мне с этим делать?


Название: Re: Перехват qFatal
Отправлено: mutineer от Май 14, 2012, 15:29
Смысл его перехвата в выводе креш-сообщения не в консоль


Название: Re: Перехват qFatal
Отправлено: xokc от Май 14, 2012, 15:34
Дак не даёт оно мне вывести его. В перехватчике генерю событие и отправляю его своей системе логирования. Но пока идёт раскрутка цикла обработки сообщений приложение уже шандарахнулось по abort(). В итоге сообщения об ошибке нет уже нигде.


Название: Re: Перехват qFatal
Отправлено: Akon от Май 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;
}
А вы хотите цикл обработки сообщений.


Название: Re: Перехват qFatal
Отправлено: xokc от Май 14, 2012, 15:53
С чего вы взяли, что удастся корректно завершить программу?
Понятно, что это сильно будет зависеть от рода ошибки. Но ведь раз уж я устанавливаю собственный обработчик ошибок и библиотека вроде-бы предоставляет мне соответствующий инструментарий - может всё-таки лучше мне решать, что делать в случае фатальной ошибки?

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


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

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


Название: Re: Перехват qFatal
Отправлено: Igors от Май 14, 2012, 16:07
Не понял о чём тут. Любая система неизбежно будет зависеть от тех компонент, на которых она написана.
Диагностика должна быть независимой. Напр перехватив обработчик Вы сможете записать ошибку в файл - если будете пользоваться напр системными ф-циями записи и вызывать их тут же. Но если логирование требует механизма событий  (который уже приказал долго жить) - записать вряд ли удастся


Название: Re: Перехват qFatal
Отправлено: xokc от Май 14, 2012, 16:19
Например, синхронный вывод сообщения в консоль или сброс сообщения в лог-файл никак не зависят от работы цикла сообщений.
Ну да. Только вот они зависят от работоспособности файловой и дисковой подсистем.

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


Название: Re: Перехват qFatal
Отправлено: Akon от Май 14, 2012, 16:50
Смысл перехвата в возможности сделать еще что либо специфичное. Но эта специфичная обработка не должна быть связана с функциями приложения. Оно должно умереть по замыслу разработчика (троллей). Цикл обработки сообщений - это функция приложения.


Название: Re: Перехват qFatal
Отправлено: xokc от Май 14, 2012, 17:39
Я Ваше мнение понял, хотя с ним и не согласен. Дискуссию при этом полагаю для себя закрытой.