Условия несрабатывания try except

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Условия несрабатывания try except

Сообщение NTFS »

Добрый день.

Столкнулся с проблемой. Пишу безопасное серверное приложение. Вылизанный код основного модуля, где все 99% надежно, и произвольный перегружаемый метод, где может и рвануть Access Violation.

По наивности, думал, что использование конструкции

Код: Выделить всё

try
   MainServerMethod()
except
   on E:Exception do
      ..
end
FinalServerMethod()

должно при любом раскладе (если я не использую вызовы dll в MainServerMethod) дать мне безопасное выполнение. Т.е, FinalServerMethod выполнится всегда.

Но!!! уже три раза, внутри MainServerMethod (да, там сложная структура, много классов, обращение к БД и прочее) возникает Access Violation и программа ПАДАЕТ

Есть ли какие-то условия, при которых try except не срабатывает?
Думал на Runtime Error, но при подключении модуля SysUtils они по-любому преобразуются в Exception

Весь сервер - один exe файл. DLL на FreePascal давно не делаю, это мертвый номер. Но тут выясняется, что и в одном исполнимом файле может быть веселье.

Среда компиляции: FPC 2.6.2, Linux32
Среда выполнения: Linux32
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Представь себе повреждение кучи, например такое, что вызов EAccessViolation.Create будет приводить к повторному нарушению доступа к памяти. То же самое касается повреждений стека. Наконец, если даже удалось создать и объект исключения и начать раскрутку стека, то по ходу дела будет выполняться код из блоков finally, который может натворить что угодно, прежде чем управление попадет в нужный блок except.

Так что использование try..except абсолютно ничего не гарантирует.
NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Сообщение NTFS »

Решение? Не хочется писать сервер на Java или C++, там это можно обеспечить, но я их не люблю и не умею готовить.
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

NTFS писал(а):там это можно обеспечить


Ой ли?
На жабке от таких проблем может быть и спасет автоматический сборщик, виртуальная машина, и то, что сам язык многих безобразий не позволяет, но вот для С++ описанную ситуацию сотворить куда легче, чем в freepascal. То, что описывает Sergei I. Gorelkin в принципе верно для любого компилируемого [в машиный код] языка программирования. Общее зло, так сказать.
Последний раз редактировалось SSerge 11.03.2013 12:04:43, всего редактировалось 1 раз.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Решение может быть только одно: при ошибках типа access violation завершать процесс немедленно, попросив систему создать дамп памяти, потом по этому дампу искать и исправлять причину.
NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Сообщение NTFS »

Ошибся, вместо С++ имел в виду C#, конечно.

Задача в общем случае такова: какое бы безобразие не происходило в методе MainMethod, всегда должен выполниться FinalMethod.

Добавлено спустя 3 минуты 16 секунд:
Оно, конечно, можно делать так:

Код: Выделить всё

#!/bin/sh

./prog_mainmethod
./prog_finalmethod


Но хотелось бы не подниматься до уровня консоли.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Разделение на процессы сработает, да. Его необязательно делать на уровне консоли, можно запускать процессы и из своей программы или, для Windows, пользоваться соответствующими механизмами COM (out-of-process server).
xdsl
постоялец
Сообщения: 131
Зарегистрирован: 15.01.2009 12:49:03

Сообщение xdsl »

access violation точно не внутри FinalServerMethod() или позже?
NTFS
постоялец
Сообщения: 388
Зарегистрирован: 05.11.2007 13:57:50
Откуда: Краснодар
Контактная информация:

Сообщение NTFS »

Однозначно внутри MainMethod.

Я проблему уже решил переходом на sh-скрипты, где сложные элементы логики оформлены в виде исполнимых файлов. Все-таки операционка в общем случае работает лучше, чем программа на FPC.
xdsl
постоялец
Сообщения: 131
Зарегистрирован: 15.01.2009 12:49:03

Сообщение xdsl »

Н-да, даже и не понять, как воспроизвести. Вот такой код:

Код: Выделить всё

{$mode objfpc}
 var p:^byte=nil;
begin
 try p^:=1; except end;
 writeln('handled');
end.

дает handled
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

А что вы ожидали получить?
Обработчик сработал, и дальше пошла программа выполняться после обработчика.
xdsl
постоялец
Сообщения: 131
Зарегистрирован: 15.01.2009 12:49:03

Сообщение xdsl »

SeZuka писал(а):А что вы ожидали получить?
Обработчик сработал, и дальше пошла программа выполняться после обработчика.

Именно это и ожидал получить.

Пытаюсь понять, как можно смоделировать ситуацию, озвученную в начале треда: viewtopic.php?p=70482#p70482
Что надо написать вместо p^:=1, чтобы появился необработанный access violation? Пока ничего в голову не приходит.
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

Не совсем понятно чего хотите. Но если вам хочется получить все-таки ошибку, тогда сделайте ее в обработчике.

Код: Выделить всё

{$mode objfpc}
var p:^byte=nil;
begin
try
p^:=1;
except
p^:=2;
end;
writeln('handled');
end.
xdsl
постоялец
Сообщения: 131
Зарегистрирован: 15.01.2009 12:49:03

Сообщение xdsl »

Автор треда утверждает, что в его случае access violation, возникающий в блоке try, не обрабатывается в блоке except.

Мне хочется смоделировать такую ситуацию и убедиться, что такое вообще возможно. Вот что такое надо ухитриться сотворить в блоке try?
SeZuka
постоялец
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05

Сообщение SeZuka »

xdsl писал(а):Автор треда утверждает, что в его случае access violation, возникающий в блоке try, не обрабатывается в блоке except.

Автор утверждает что у него не срабатывает FinalServerMethod который идет после except .. end так что возможно что ошибка в самом обработчике.
Лет 10 назад делал один крупный проект на дельфи, в нем был один общий обработчик, который писал в лог в файл и делал снимки экрана во время ошибки. Так вот была такая ситуация, когда при любой ошибке программа полностью вылетала с AV, оказалось что программу запускали из сетевой папки на которой стоял запрет на запись. В итоге при ошибке программа пыталась записать лог с изображением, но не могла этого сделать и получала еще одну ошибку уже в самом обработчике except .. end и после этого полностью падала.
Ответить