Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Убрать Microsoft Visual c++ runtime library error 
V
    Опции темы
borisbn
Дата 2.10.2014, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Здравствуйте!

Хочу сделать костыль для программ, которые должны работать 24x7, но которые иногда "падают".
Нашёл такую функцию - RegisterApplicationRestart.
Сделал вот такой исходник, который нужно просто включить в проект
Код
DWORD WINAPI Recover( PVOID /*pContext*/ )
{
    ApplicationRecoveryFinished( FALSE );
    return 0;
}

int initAutoRecovery()
{
    int nArgs = 0;
    LPWSTR * szArglist = CommandLineToArgvW( GetCommandLineW(), & nArgs );
    std::wstring args;
    for ( int i = 1; i < nArgs; i++ ) {
        args += std::wstring( szArglist[ i ] ) + L" ";
    }
    LocalFree(szArglist);

    RegisterApplicationRestart( args.c_str(), 0 );
    RegisterApplicationRecoveryCallback( Recover, 0, 0, 0 );
    return 42;
}

int dummy = initAutoRecovery();

При падении приложения оно само перезапускает себя. И это работает для неструктурированных исключений (обращение по NULL, деление на 0 и т.п.), но если происходит структурированное исключение, например std::bad_alloc, то выдаётся сообщение
Цитата
Microsoft Visual C++ runtime library
Runtime error!

после нажатия на Ok программа просто закрывается и всё.
Мне нужно, чтобы при выкидывании структурированных исключений программа просто "падала", тогда система Microsoft Error Reporting её просто перезапустит.

В этой теме на СО предлагают обернуть весь код try - catch (...). Я такое сделал, но, если исключение происходит не в GUI-потоке, то сообщение всё равно появляется. Оборачивать все потоки в try - catch не вариант, т.к. хотелось бы получить результат одним простым движением, а не перелопачивать кучу своего и чужого кода.
Ещё в одной теме советуют либо переписать функцию abort (пробовал - не работает) либо вызвать функцию _set_abort_behavior (пробовал - с тем же результатом).

Вопрос: как отключить вывод этого окна или как перехватить его вывод и вместо него сделать что-нибудь нехорошее (например записать что-нибудь по NULL) ?

P.S. Не ругайте, пожалуйста, но я не помню как по-русски будет unexpected exception, поэтому назвал его неструктурированным ))

P.P.S. Я, естественно, понимаю, что нужно правильно писать программы, нужно всё и вся отлаживать, делать try - catch на любой чих и т.п., но есть пара нюансов, которые вам, скорее всего, неинтересны.

Это сообщение отредактировал(а) borisbn - 2.10.2014, 13:17


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
xvr
Дата 2.10.2014, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Поробуйте поиграться функциями set_terminate и  set_unexpected

PM MAIL   Вверх
borisbn
Дата 2.10.2014, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



xvr, спасибо, но, похоже, я зря выбросил комментарии из кода ))
На самом деле функция initAutoRecovery выглядит у меня так
Код
int initAutoRecovery()
{
    //_set_abort_behavior( _CALL_REPORTFAULT, _CALL_REPORTFAULT | _WRITE_ABORT_MSG );
    //set_terminate( my_terminate );
    //set_unexpected( my_terminate );
...


Другими словами - пробовал... не помогает


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Amp
Дата 2.10.2014, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(borisbn @  2.10.2014,  13:55 Найти цитируемый пост)
На самом деле функция initAutoRecovery выглядит у меня так

Она при первом старте выполняется или только после крэша?
PM MAIL   Вверх
borisbn
Дата 2.10.2014, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(Amp @  2.10.2014,  14:28 Найти цитируемый пост)
Она при первом старте выполняется или только после крэша? 

При старте программы
Цитата(borisbn @  2.10.2014,  13:15 Найти цитируемый пост)
int dummy = initAutoRecovery();

dummy - статическая переменная для вызова initAutoRecovery()



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
DarthTon
Дата 8.10.2014, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

LPTOP_LEVEL_EXCEPTION_FILTER previousFilter = nullptr;

LONG WINAPI Filter( PEXCEPTION_POINTERS ExceptionInfo )
{
    // Remove current filter
    if (previousFilter)
        SetUnhandledExceptionFilter( previousFilter );

    // rethrow unhandled win32 exception to WER
    RaiseException( EXCEPTION_NONCONTINUABLE_EXCEPTION, EXCEPTION_NONCONTINUABLE, 0, NULL );
    return EXCEPTION_EXECUTE_FAULT;
}

int main( int /*argc*/, char* /*argv*/[] )
{ 
    previousFilter = SetUnhandledExceptionFilter( &Filter );
}


Собствено, в Filter можно уже и самому перезапустить приложение и не надеяться на WER.

Это сообщение отредактировал(а) DarthTon - 8.10.2014, 14:14
PM MAIL   Вверх
borisbn
Дата 8.10.2014, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



DarthTon, не помогает. Всё равно выдаётся это окошко с ссобщением

Цитата
Microsoft Visual C++ runtime library
Runtime error!



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
DarthTon
Дата 8.10.2014, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А можно мне какой-нибудь тестовый кусок кода? А то в моём случае работало с С++ ексепшенами?
PM MAIL   Вверх
borisbn
Дата 8.10.2014, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



DarthTon, я добавил в начало функции Filter код
Код
::MessageBoxA( 0, "in Filter", "Filter", MB_OK );

и не видел этого сообщения.
Цитата(DarthTon @  8.10.2014,  15:29 Найти цитируемый пост)
А можно мне какой-нибудь тестовый кусок кода?

Так с налёту трудно.. У меня проект на Qt и я запускаю Qt-шный поток, в котором и выкидывается std::bad_alloc(). Я специально в QThread::run() сделал std::vector::resize( 3 ГБ ) и вижу это сообщение от Microsoft.
Вот если сделать обращение по нулевому адресу, то я захожу в функцию Recover и всё идёт по плану.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
DarthTon
Дата 8.10.2014, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Возможно, что-то потом переопределяет UnhandledExceptionFilter либо вызывает abort() напрямую, т.к. UnhandledExceptionFilter вроде ловит все С++ исключения нормально. Надо бы глянуть стек вызова и SEH-фреймы в TIB когда выпадает Runtime error!.
PM MAIL   Вверх
korian
Дата 9.10.2014, 02:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

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



Цитата(borisbn @  2.10.2014,  12:15 Найти цитируемый пост)
то выдаётся сообщение

это релиз билд?
PM   Вверх
Dem_max
Дата 9.10.2014, 06:26 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



UnhandledExceptionFilter ничего не знает от С++ исключениях, он ловит SEH исключения.

читать по 2 ссылкам:
http://msdn.microsoft.com/ru-ru/library/1deeycx5.aspx
http://msdn.microsoft.com/ru-ru/library/5z4bw5h5.aspx

Это сообщение отредактировал(а) Dem_max - 9.10.2014, 06:27


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
borisbn
Дата 9.10.2014, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



korian, и в релизе и в дебаге поведение одинаковое, если запускать из проводника. Если запускать из студии под дебагом, то, ессно, студия останавливается в том месте, где было вызвано исключение, но мне  нужно не это.

Dem_max, поставил опцию /EHa и сделал такой код
Код
void trans_func( unsigned int, EXCEPTION_POINTERS* ) {
    ::MessageBoxA( 0, "in trans_func", "trans_func", MB_OK );
    int * p = 0;
    *p = 42;
}

int initAutoRecovery() {
    _set_se_translator( trans_func );
...
}

сообщение "in trans_func" не показывается, а неубиенное окно от M$ - да.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
borisbn
Дата 9.10.2014, 09:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



 smile 
user posted image
забавно смотрится... Может это - ответ на мой вопрос )))


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 9.10.2014, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



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


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


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

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


 




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


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

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