![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Перехват всех ошибок в консольных приложениях
Сало © (2007-01-23 14:49:00)Если в GUI приложениях можно использовать ApplicationEvents, то в в консольных использование этого компонента не целесообразно. Как же обработать все исключения, возникшие в консольном приложении и не обработанные локально?
В библиотеке JCL можно перехватить все ошибки, но все равно
ошибка вылетает...
Джо (2007-01-23 17:10:00) [1]> Почему?
Для корректной работы конструкции try/except именно и необходим SysUtils, чего же тут непонятного? :)
П.С. Там в секции инициализации SysUtils.pas имеется вызов InitExceptions, который, собственно, назначает все обработчики исключений.
властелин колхоза (2007-01-23 17:06:00) [2]> [2] Джо © (23.01.07 15:02)
Раз уж об этом речь зашла...
{$APPTYPE CONSOLE}
program Salo;
var
A,B:Integer;
begin
try
ReadLn(A);
B:=10 div A;
WriteLn(B);
ReadLn;
except
WriteLn('Страшенная ошибка!');
ReadLn;
end;
end.
при вводе А=0 тихо вылетает.
{$APPTYPE CONSOLE}
program Salo;
uses
SysUtils;
var
A,B:Integer;
begin
try
ReadLn(A);
B:=10 div A;
WriteLn(B);
ReadLn;
except
WriteLn('Страшенная ошибка!');
ReadLn;
end;
end.
в аналогичных условиях выводит в консоль сообщение об ошибке. Почему?
Игорь Шевченко (2007-01-23 16:37:00) [3]
> Как же обработать все исключения, возникшие в консольном
> приложении и не обработанные локально?
SetUnhandledExceptionFilter ? :)
http://msdn2.microsoft.com/en-us/library/ms680634.aspx
Сало (2007-01-23 16:32:00) [4]В каждом потоке можно также подменить RaiseException, в чем проблема?
Сергей М. (2007-01-23 15:56:00) [5]
> Сало © (23.01.07 15:29) [4]
К [3] это не имеет ни малейшего отношения.
Сало (2007-01-23 15:29:00) [6]Да ладно. JCL замещает вызов системного RaiseException своим. Но!
procedure HookedRaiseException(ExceptionCode, ExceptionFlags, NumberOfArguments: DWORD;
Arguments: PExceptionArguments); stdcall;
const
cDelphiException = $0EEDFADE;
cNonContinuable = 1;
begin
if (ExceptionFlags = cNonContinuable) and (ExceptionCode = cDelphiException) and
(NumberOfArguments = 7) and (DWORD(Arguments) = DWORD(@Arguments) + 4) then
DoExceptNotify(Arguments.ExceptObj, Arguments.ExceptAddr, False);
Kernel32_RaiseException(ExceptionCode, ExceptionFlags, NumberOfArguments, PDWORD(Arguments));
end;
Если закомментировать вызов Kernel32_RaiseException, то получаю privileged instruction. Что делать?
Сергей М. (2007-01-23 15:11:00) [7]
> Как же обработать все исключения, возникшие в консольном
> приложении и не обработанные локально?
Никак.
И в GUI-приложении, использующем тот самый якобы "волшебный" ApplicationEvents - тоже никак.
Под "никАком" подразумевается общий случай - процесс приложения может иметь более чем один кодовый поток, что подразумевает индивидуальную "ручную" обработку исключений в каждом из потоков, за исключением основного, где "чайник" до поры до времени может надеяться на Application.OnException
Джо (2007-01-23 15:02:00) [8]
program Salo;
begin
try
// программа
except
// обработка
end;
end.
Казалось, куда проще? :)
tesseract (2007-01-23 14:57:00) [9]Try.. except - он сильно локален?