Проблема с AccessViolation
От: Sidorovich  
Дата: 18.08.06 06:46
Оценка:
Есть серверное приложение написаное на C++ и работающее в среде Windows (Linux). Это приложение может подгружать различные модули для выполнения различных задач. А вот в этих модулях может произойти AV. И как только он происходит, то все это приложение валится в хлам. Хотелось бы как-то защититься от AV, который происходит в сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?
Re: Проблема с AccessViolation
От: alexeiz  
Дата: 18.08.06 07:50
Оценка:
Здравствуйте, Sidorovich, Вы писали:

S>Есть серверное приложение написаное на C++ и работающее в среде Windows (Linux). Это приложение может подгружать различные модули для выполнения различных задач. А вот в этих модулях может произойти AV. И как только он происходит, то все это приложение валится в хлам. Хотелось бы как-то защититься от AV, который происходит в сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?


Не имеет смысла это делать. Память у тебя разделяется между модулями и приложением. Невозможно дать какую-либо гарантию, что модуль не испортит память (или другие ресурсы) основного приложения.
Re[2]: Проблема с AccessViolation
От: Aera Беларусь  
Дата: 18.08.06 08:04
Оценка:
Здравствуйте, alexeiz, Вы писали:


A>Не имеет смысла это делать. Память у тебя разделяется между модулями и приложением. Невозможно дать какую-либо гарантию, что модуль не испортит память (или другие ресурсы) основного приложения.


Наверное можно было бы дать гарантию, если бы модули были приложенияи и общались с приложением через разделяемую память, в таком случае можно было бы ограничить их влияние на работоспособность приложения, а обработка AV и аварийное завершение ложилось бы на плечи операционной системы.
--
RedApe
Re[3]: Проблема с AccessViolation
От: Sidorovich  
Дата: 18.08.06 08:53
Оценка:
Здравствуйте, Aera, Вы писали:

A>Здравствуйте, alexeiz, Вы писали:



A>>Не имеет смысла это делать. Память у тебя разделяется между модулями и приложением. Невозможно дать какую-либо гарантию, что модуль не испортит память (или другие ресурсы) основного приложения.


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


Дык, нужно хотя бы в обработчике сообщить (хотя бы в лог), что у нас произошла аварийная обстановка и благополучно закрыться. Вопрос не снят, но переформулирован
Re: Проблема с AccessViolation
От: bobik_ Украина http://farnetstat.narod.ru/
Дата: 18.08.06 11:44
Оценка:
Здравствуйте, Sidorovich, Вы писали:

S>Есть серверное приложение написаное на C++ и работающее в среде Windows (Linux). Это приложение может подгружать различные модули для выполнения различных задач. А вот в этих модулях может произойти AV. И как только он происходит, то все это приложение валится в хлам. Хотелось бы как-то защититься от AV, который происходит в сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?


Последний проект которым я занимался, это сервер под Linux, по сути своей не важно чем он занимается вопрос не в том. Дело в том что если у вас винда то любой VA можно перехватить по catch(...), но это совсем не годится для линукса, так как в этом случае апликухе будет послан сигнал как то например 11(SIGSEGV), который и сигнализарует о такой поганой ситуации. Как однозначно лечить такие моменты в рантайме я не знаю, однозначно нужно делать так что такие моменты возникали как можно реже, но если они возникли то нужно как можно быстрее уведомить разработчика. Поэтому у меня на самом старте регистрируется обработчик сигналов и по приходу которых посылается email с описанием проблемы, конечно это можно положить и в лог. А на сколько оперативно вы отреагируете — это уже административный вопрос.
Re: Проблема с AccessViolation
От: Andrew_D  
Дата: 18.08.06 20:20
Оценка:
Здравствуйте, Sidorovich, Вы писали:

S>Есть серверное приложение написаное на C++ и работающее в среде Windows (Linux). Это приложение может подгружать различные модули для выполнения различных задач. А вот в этих модулях может произойти AV. И как только он происходит, то все это приложение валится в хлам. Хотелось бы как-то защититься от AV, который происходит в сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?


В винде можно "повесить" на поток транслятор структурных исключений
ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vccrt/html/280842bc-d72a-468b-a565-2d3db893ae0f.htm
Re: Проблема с AccessViolation
От: Аноним  
Дата: 18.08.06 20:47
Оценка:
Единственный надежный способ уберечься от AV в других модулях — это запуск в другом процессе.
Иначе есть верный шанс, что будет порушена память у вас.
Re[2]: Проблема с AccessViolation
От: remark Россия http://www.1024cores.net/
Дата: 19.08.06 07:16
Оценка: -1
Здравствуйте, alexeiz, Вы писали:

A>Здравствуйте, Sidorovich, Вы писали:


S>>Есть серверное приложение написаное на C++ и работающее в среде Windows (Linux). Это приложение может подгружать различные модули для выполнения различных задач. А вот в этих модулях может произойти AV. И как только он происходит, то все это приложение валится в хлам. Хотелось бы как-то защититься от AV, который происходит в сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?


A>Не имеет смысла это делать. Память у тебя разделяется между модулями и приложением. Невозможно дать какую-либо гарантию, что модуль не испортит память (или другие ресурсы) основного приложения.


Достаточно часто AV происходит при записи/чтении либо нулевого указателя, либо "своего" удалённого указателя, либо вокруг "своего" буфера. Поэтому достаточно часто подавление AV даёт положительные результаты, т.к. накрывается только один поток, а не все, и не все теряют свои данные + сервер остаётся доступен.

Такая ситуация достаточно редка:
int* p = rand();
*p = 0;




1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Проблема с AccessViolation
От: Sidorovich  
Дата: 21.08.06 11:29
Оценка:
Здравствуйте, bobik_, Вы писали:


сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?

_>Последний проект которым я занимался, это сервер под Linux, по сути своей не важно чем он занимается вопрос не в том. Дело в том что если у вас винда то любой VA можно перехватить по catch(...), но это совсем не годится для линукса, так как в этом случае апликухе будет послан сигнал как то например 11(SIGSEGV), который и

Я тоже так думал. Но ошибся. catch (...) AV не перехватил .
Re[3]: Проблема с AccessViolation
От: Аноним  
Дата: 21.08.06 11:53
Оценка:
Не советывал бы ловить AV, особенно по catch(...), но посмотри здесь:
http://rsdn.ru/Forum/Message.aspx?mid=2055361&only=1
Автор: kov_serg
Дата: 12.08.06
Re[4]: Проблема с AccessViolation
От: gear nuke  
Дата: 21.08.06 16:07
Оценка:
Здравствуйте, Sidorovich, Вы писали:

S> Дык, нужно хотя бы в обработчике сообщить (хотя бы в лог), что у нас произошла аварийная обстановка и благополучно закрыться. Вопрос не снят, но переформулирован


Для виндоса — см. SetUnhandledExceptionFilter. UnhandledExceptionFilter ловит необработанные исключения в любом треде.
Кросплатформенно — видимо signal с SIGSEGV, но сам не пользовал
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: Проблема с AccessViolation
От: McQwerty Россия  
Дата: 28.08.06 11:45
Оценка:
Здравствуйте, remark, Вы писали:

S>>>Есть серверное приложение написаное на C++ и работающее в среде Windows (Linux). Это приложение может подгружать различные модули для выполнения различных задач. А вот в этих модулях может произойти AV. И как только он происходит, то все это приложение валится в хлам. Хотелось бы как-то защититься от AV, который происходит в сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?


R>Достаточно часто AV происходит при записи/чтении либо нулевого указателя, либо "своего" удалённого указателя, либо вокруг "своего" буфера. Поэтому достаточно часто подавление AV даёт положительные результаты, т.к. накрывается только один поток, а не все, и не все теряют свои данные + сервер остаётся доступен.


R>Такая ситуация достаточно редка:

R>
R>int* p = rand();
R>*p = 0;
R>


Это, как раз, очень частая ситуация:
struct xxx
{
    int * p;
};

xxx a;
if (a. p)
    * a. p = 0; // не выглядит, как rand, однако, таковой явдяется
else
    throw ("Блин, память не выделена!");

R>
Ну, это мы завсегда
Re[2]: Проблема с AccessViolation
От: trophim Россия  
Дата: 28.08.06 19:23
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Единственный надежный способ уберечься от AV в других модулях — это запуск в другом процессе.

А>Иначе есть верный шанс, что будет порушена память у вас.

Ну, почему? Если произошел AV по чтению, то вообще еще ничего не порушено и можно со спокойной совестью сказать пользователю, что мол извините, лавочка закрывается в связи с некорректным поведением одного из компонентов, и нормально безболезненно завершить приложение (при этом не вызывать больше функций из того нехорошего модуля, чтобы не усугублять). По крайней мере текущие данные не будут безвозвратно потеряны.
[EOF]
Let it be! — Давайте есть пчелу!
Re[3]: Проблема с AccessViolation
От: alexeiz  
Дата: 28.08.06 20:32
Оценка:
Здравствуйте, trophim, Вы писали:

T>Здравствуйте, <Аноним>, Вы писали:


А>>Единственный надежный способ уберечься от AV в других модулях — это запуск в другом процессе.

А>>Иначе есть верный шанс, что будет порушена память у вас.

T>Ну, почему? Если произошел AV по чтению, то вообще еще ничего не порушено


Допустим происходит банальный buffer overflow, переписывается стек (и адрес возврата на нём), а при попытке возврата происходит AV по чтению. Что ты тогда будешь делать?
Re[3]: Проблема с AccessViolation
От: apple-antonovka  
Дата: 28.08.06 21:41
Оценка: +1
Ага. Сервер банковских транзакций. Клиент снимает 10000$. Валится AV. Гасится, сумма снимается со счета клиента, но не выдается. А потом изза нарушенной логики выдается другому клиенту который снимает 100$. Зато сервер работает
Любые исключения надо не гасить, а писать в лог, дампить себя, и, если важна работа сервера — рестартится.
Но лучше даже не рестартится при возмоджности тк это может быть признаком "ощупывания" хакером сервера на предмет наличия buffer-overflow, в таком случае хакер уже все нащупал и следующим ходом снимет себе 10000$
Re: Проблема с AccessViolation
От: volk  
Дата: 28.08.06 23:05
Оценка:
Здравствуйте, Sidorovich, Вы писали:

S>Есть серверное приложение написаное на C++ и работающее в среде Windows (Linux). Это приложение может подгружать различные модули для выполнения различных задач. А вот в этих модулях может произойти AV. И как только он происходит, то все это приложение валится в хлам. Хотелось бы как-то защититься от AV, который происходит в сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?


Ситуация очень мерзкая и ничем не отличается от того случая, когда AV выскакивает в твоем собственном исполнимом модуле. Можно пытаться перехватывать сигналы Linux-а (кажется, SIGSEGV, 11), в Win должен спасти SEH и SetUnhandledExceptionFilter или как его там.

Но красиво и хорошо сделать не получится. Нужна либо стандартная связка fork/IPC, либо дополнительная программка-Watchdog, которая снова запустит упавшее приложение и передаст ему аргументы ком. строки, по которым оно сможет восстановить свое состояние на момент, предшествующий падению. (Для этого надо, конченно, это состояние периодически сохранять.)
Тот, кто желает, но не делает, распространяет чуму.
Re[4]: Проблема с AccessViolation
От: trophim Россия  
Дата: 29.08.06 18:32
Оценка:
Здравствуйте, apple-antonovka, Вы писали:

AA>Ага. Сервер банковских транзакций. Клиент снимает 10000$. Валится AV. Гасится, сумма снимается со счета клиента, но не выдается. А потом изза нарушенной логики выдается другому клиенту который снимает 100$. Зато сервер работает

AA>Любые исключения надо не гасить, а писать в лог, дампить себя, и, если важна работа сервера — рестартится.
AA>Но лучше даже не рестартится при возмоджности тк это может быть признаком "ощупывания" хакером сервера на предмет наличия buffer-overflow, в таком случае хакер уже все нащупал и следующим ходом снимет себе 10000$

А вот плохой пример — транзакция на то и нужна, что при AV хоть прога и закроется с сохранением состояния, но транзакция будет отменена, ведь внутри нее произошло исключение. На то она и транзакция. Так что давайте другой пример.

А вообще я говорил про "обычные" (не надо меня просить определить категорию обычности) программы, типа Ворда, который даже при падении сохраняет все же текущее состояние.
[EOF]
Let it be! — Давайте есть пчелу!
Re: Проблема с AccessViolation
От: Vain Россия google.ru
Дата: 29.08.06 19:05
Оценка:
Здравствуйте, Sidorovich, Вы писали:

S>только он происходит, то все это приложение валится в хлам. Хотелось бы как-то защититься от AV, который происходит в сторонних модулях и при таком событии их выгружать. Кто-то подскажет, как правильно перехватить оный AV?

Есть токо идея как это можно организовать, остальное весит на возвожностях АПИ винды.
Значит перед загрузкой "недоброкачественных" библиотек создавать для них специальный хип и загружать их в отдельные потоки. При запуске таких потоков, устанавливать для них этот хип. Таким образом, если библиотека падает — перехватывать AV -> закрывать поток -> закрывать этот хип. Единственный недостаток — придётся также выгружать/перезагружать все остальные "надоброкачественные" библиотеки, которые ещё "не успели" упасть и кушали этот хип..
Что-то вот такое, осталось только реализовать
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[5]: Проблема с AccessViolation
От: apple-antonovka  
Дата: 29.08.06 20:04
Оценка:
T>А вот плохой пример — транзакция на то и нужна, что при AV хоть прога и закроется с сохранением состояния, но транзакция будет отменена, ведь внутри нее произошло исключение. На то она и транзакция. Так что давайте другой пример.
Транзакция ведь кем-то обслуживается, правда?

T>А вообще я говорил про "обычные" (не надо меня просить определить категорию обычности) программы, типа Ворда, который даже при падении сохраняет все же текущее состояние.

Для Врода сохранить некорректные данные лучше чем ничего не сохранить.
Для сервера обычно лучше ничего не делать если чтото "не так".
Даже ворд перезапускается после любого AV, а ведь мог бы погасить, сказать юзеру что-то мол "я тут сохранил твой текст, малоли" и дальше работать.
Re[6]: Проблема с AccessViolation
От: trophim Россия  
Дата: 30.08.06 06:05
Оценка:
Здравствуйте, apple-antonovka, Вы писали:

T>>А вот плохой пример — транзакция на то и нужна, что при AV хоть прога и закроется с сохранением состояния, но транзакция будет отменена, ведь внутри нее произошло исключение. На то она и транзакция. Так что давайте другой пример.

AA>Транзакция ведь кем-то обслуживается, правда?

Ну, правда. Только если исключения возникают, то транзакция и не начинается вовсе. Даже если исключения высыпаются в коде который занимается фиксированием того факта, что началась транзакция, то ничего критичного не произойдет — эта самая транзакция вообще не начнется, ибо валятся AV. Т.е. часть программы, занимающаяся самим процессом проведения транзакций должна быть к исключениям особенно чувствительна: чуть что не так — сразу выключаем систему.
Т.о. я утверждаю что транзакция либо вся заканчивается и внутри нее не было вообще никаких AV, либо вся она отменяется.
Примерно вот так. Что некорректно сформулировал?

T>>А вообще я говорил про "обычные" (не надо меня просить определить категорию обычности) программы, типа Ворда, который даже при падении сохраняет все же текущее состояние.

AA>Для Врода сохранить некорректные данные лучше чем ничего не сохранить.
AA>Для сервера обычно лучше ничего не делать если чтото "не так".
AA>Даже ворд перезапускается после любого AV, а ведь мог бы погасить, сказать юзеру что-то мол "я тут сохранил твой текст, малоли" и дальше работать.

Дальше работать это совершенно не приемлимо в любом случае — сервер это или Ворд. Завершение работы в любом случае. А уж восстановится программа потом или нет...
[EOF]
Let it be! — Давайте есть пчелу!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.