В мире софта столько говорят об обработке ошибок, о грамотном управлении ошибками, о полезности ошибок, что привыкаешь, написав хорошую обработку ошибок, чувствовать себя защищённым от любых случайностей.
А между тем, контроль ошибок, assertionы и прочее - это, скорее, защита от случайно допущенных закономерностей. Настоящая случайная ошибка - это когда процессор сложил два и два и получил пять. Никакие try...except до конца от этого не защитят.
Слава богу, что такое редкость.
(С другой стороны... )
А между тем, контроль ошибок, assertionы и прочее - это, скорее, защита от случайно допущенных закономерностей. Настоящая случайная ошибка - это когда процессор сложил два и два и получил пять. Никакие try...except до конца от этого не защитят.
Слава богу, что такое редкость.
(С другой стороны... )
если невозможно выделить большой участок памяти, то, возможно, возможно выделить маленький участок?
закончившийся стек -- это конечно плохо, но за последнее значение можно ручаться всегда. (а за остальные -- нет. так что "стек в сторону уменьшения" -- это хорошо, но там может быть то, что нам совсем не нужно... т.е. мы не можем обещать, что ретёрн вернёт нас не в случайную точку программы или вообще куда-нибудь в данные...) с другой стороны стек "вдруг" не заканчивается, для этого кто-то должен в него мусорить, причём весьма активно (рекурсия, например). либо мы сами, либо то, что мы вызываем. другими словами то, что уже заранее известно. т.е. это указывает на ошибку либо нас, либо стандартной библиотеки. кроме случая с рекурсией, которого надо просто избегать.
ошибки же типа "пропало подключение ко всему" или "закончилось место на диске" -- вообще детский сад, в любом учебнике по языкам всегда проверяют, что вернул ф-опен, допустим.
// zHz
To Be Continued...
клинические случаи типа "отказал процессор" или "пришёл злой А и всех убил" (вариант: пришёл вирус, испортил нам стек, забил его почти до вершины) обрабатывать не надо, ибо даже если мы выйдем из прогрммы без позорного грохота, система вряд ли будет нормально работать.
можно, конечно каждый раз проверять, получилось 2+2==4 или что-то ещё. это снизит вероятность ошибок логики и случайного шума, но полной гарантии опять-таки не даст, что данные после вычисления и проверки не полетят на... юг. это вообще другой _класс_ ошибок, которые либо ни от чего не зависят и происходят 1 раз в 10 лет, либо от чего-то зависят, но являются не только "нашей" проблемой, но и проблемой всего компьютера. т.е. не то, чтобы "защищаться бесполезно", а "защищатсья нет смысла"...
если я где-то не прав, поправьте, чтобы не жил в неведении...
// zHz
MsgBox в в условиях нехватки памяти сразу выдавать бесполезно (это вроде провоцирует выделение памяти совсем даже не нашей - APiлки), нам бы рухнуть как-нибудь с минимальными потерями данных и освободить все занятые ресурсы. Можно в логи что-нибудь выплюнуть.
если невозможно выделить большой участок памяти, то, возможно, возможно выделить маленький участок?
Нет.
(а за остальные -- нет. так что "стек в сторону уменьшения" -- это хорошо, но там может быть то, что нам совсем не нужно... т.е. мы не можем обещать, что ретёрн вернёт нас не в случайную точку программы или вообще куда-нибудь в данные...)
Можем. Напоминаю, речь об обработке предсказуемых ошибок. Например, "стек кончился" - ошибка предсказуемая, но в таком случае весь уже использованный стек вполне корректен, и не может меняться как попало.
Наоборот, если стек испорчен "назад", то это непредсказуемая ошибка, и сделать здесь уже вообще ничего нельзя.
ошибки же типа "пропало подключение ко всему" или "закончилось место на диске" -- вообще детский сад, в любом учебнике по языкам всегда проверяют, что вернул ф-опен, допустим.
Это только кажется так. А на деле ты редко "просто пишешь в файл". Обычно ты пишешь в файл по какой-то причине. Например, случилась ошибка, ты хочешь сохранить о ней информацию в лог для программиста, а в лог не сохраняется! Ещё хуже: ты попытался применить транзакцию - получил ошибку. Попытался откатить - ошибка. Разорвал соединение, хочешь выставить флаг в локальных данных "транзакция откачена" - ошибка. Хочешь записать её в лог - ошибка. Хочешь отправить письмо администратору - ошибка. Что программе делать? Как минимизировать разрушения от всех этих ошибок? Она бы и рада кому-то пожаловаться, но ей же всюду затыкают рот.
другими словами, любая программа должна обрабатывать ошибки до того самого уровня, как и Индекс, ИМХО.
Чо?
память надо выделать не по 3 байта, а "чушками" по 3 мегабайта, а использовать по мере необходимости. тогда если вдруг окажется, что на "чушку" памяти нет, можно расчитывать, что уж на системный вызов МесседжБокс и ЕхитПроцесс памяти хватит.
Ты ведь не можешь гарантировать, что другие библиотеки в приложении будут следовать такому же правилу. Да и если будут, откуда ты знаешь, что последний блок не будет 3 мегабайта впритык? Опять же, это только виртуальная память, а физическую могут тратить и другие процессы, причём подчистую. Т.е. ни от чего это не защищает.
это вообще другой _класс_ ошибок
Я об этом и говорю. Правда, ты зря считаешь, что они происходят раз в десять лет. Редко, да. Но попробуй только разгонать процессор или видеокарту сильно выше нормы...
куда важнее, чтобы наше приложение не истекало памятью, не забивало винт, не съедало все свободные сокеты и не устраивало "бесконечных" рекурсий.
Э, ну в каком-то смысле это важнее, другое дело что нормальные приложения так себя не ведут. И обнаружить это проще.
Кстати, интересно, не тратят ли функции работы с файлами больше ресурсов, чем месседжбокс? Я вот не проверял, а это не очевидно.
Чтобы всегда было место в логах, надо их держать в отдельном относительно безопасном месте. Обычно на разделе с системой свободное место бывает. Или попробовать писать в eventlog. (в юниксах много чего страшного можно валить в /var/log/ - там место кончается крайне редко, чтоб что-то написать в лог, надо скушать 1 дескриптор и сделать 1 системный вызов - считанные килобайты (в форточках примерно также, читал). Хотя в самых жутких случаях (рухнуло все IO) не спасет) Сообщение на экран кушает уже граф подсистему -> сожрет больше.
Задача: сделать так, чтобы на третьем дне работы система не зависла намертво, потому что в этом случае поезд придётся пускать второй раз, а это не дёшево.
Какие средства? С самого начал выделяются резервные области памяти (всегда держатся в оперативной памяти), которые могут использоваться и как стек и как сегмент кода, по внутренней и внешней линии подведены два таймера, которые периодически дёргают за ножку прерывания, и программа проявляет где она находится и сколько там исполняется (WatchDog Timer). Имеются резервные ПЗУ с программой, из которых можно восстановить повреждённую память. При каждом вызове функции производится проверка на переполнение стека. Ну и т.д.
А в такой системе жёсткие требования не только к надёжности, но и к скорости работы. Писать приходится очень аккуратно, обрабатывая практически каждую возможную ошибку. И что самое страшное: кричать некому...
// ssvda