Форум: "Основная";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
ВнизМеханизм реализации исключений Найти похожие ветки
← →
vertal (2004-04-05 01:15) [0]Народ , кто-нибудь может дать мне ссылку на статью или книгу в электронном
виде , где описан механизм реализации исключений в Delphi на уровне получающегося экзешника?
← →
VMcL © (2004-04-05 10:22) [1]>>vertal (05.04.04 01:15)
По-моему на http://www.wasm.ru/ видел.
← →
Игорь Шевченко © (2004-04-05 11:32) [2]
> где описан механизм реализации исключений в Delphi на уровне
> получающегося экзешника?
?????????????????????????? переведи вопрос.
RTFS: System.pas, слова raise, finally, exception
← →
vertal (2004-04-06 00:39) [3]Я имею в виду , что с обработкой ошибок в Pascal все более-менее ясно: генерируется программное прерывание , выполняется вызов его обработчика , программа завершается.А в Delphi , что , тоже вначале генерируется программное прерывание , а как потом процессор находит его обработчик?В справке по Delphi это недостаточно подробно разъяснено.И еще меня интересует , влияет ли наличие блоков try на производительность программ в Delphi?
← →
Alex Konshin © (2004-04-06 00:57) [4]Игорь Шевченко © (05.04.04 11:32) [2]
Далеко ты его послал :) Там этих слов будет как у нас белок (собак у нас меньше).
Существует несколько механизмов exception, я не совсем уверен, какой из них сейчас используется в Delphi по умолчанию.
По try...except на стеке создается фрейм, т.ч. время все-таки затрачивается.
Поищи лучше в System.pas слово "frame", больше пользы будет.
← →
Игорь Шевченко © (2004-04-06 11:20) [5]Alex Konshin © (06.04.04 00:57)
Стандартный, вроде используется, который SEH в системе. Начиная с Delphi2, насколько мне память не изменяет.
← →
Alex Konshin © (2004-04-06 11:38) [6]Я знаю, что в VC можно выбирать. Вполне возможно, что и в Delphi уже так - не знаю, меня просто смущает, что в System.pas они поставляли условную компиляцию как раз-таки на релизацию этих фреймов. Может это для Kylix, может и нет - я не разбирался.
← →
Fay © (2004-04-06 11:41) [7]К слову... Встретил такое и торможу
procedure _RaiseExcept;
asm
{$IFDEF PC_MAPPED_EXCEPTIONS}
{ -> EAX Pointer to exception object }
MOV EDX, [ESP]
JMP _RaiseAtExcept
{$ENDIF}
{$IFDEF MSWINDOWS}
{ When making changes to the way Delphi Exceptions are raised, }
{ please realize that the C++ Exception handling code reraises }
{ some exceptions as Delphi Exceptions. Of course we want to }
{ keep exception raising compatible between Delphi and C++, so }
{ when you make changes here, consult with the relevant C++ }
{ exception handling engineer. The C++ code is in xx.cpp, in }
{ the RTL sources, in function tossAnException. }
{ -> EAX Pointer to exception object }
{ [ESP] Error address }
OR EAX, EAX
JNE @@GoAhead
MOV EAX, 216
CALL _RunError
@@GoAhead:
POP EDX
PUSH ESP
PUSH EBP
PUSH EDI
PUSH ESI
PUSH EBX
PUSH EAX { pass class argument }
PUSH EDX { pass address argument }
PUSH ESP { pass pointer to arguments }
PUSH 7 { there are seven arguments }
PUSH cNonContinuable { we can"t continue execution }
PUSH cDelphiException { our magic exception code }
PUSH EDX { pass the user"s return address }
JMP RaiseExceptionProc
{$ENDIF}
end;
Нафиг OR EAX, EAX ?
← →
Матлабист (2004-04-06 11:58) [8]try.. except|finally блоки реализованы на уровне самой Windows. Delphi просто использует єтот механизм. На самом деле все просто. Для каждого потока, селектор FS указывает на некоторую структуру (Thread Environment Block), которая содержит информацию о потоке. В частности, по смещению нуль там хранитсья адрес, куда нужно передать управление в случае возникновения исключительной ситуации.
Код на try обычно сохраняет значение ebp, адрес finally части, а также старый адрес обработчика исключения. Потом заменяет старый адрес новым. Код перед except|finally все восстанавливает. Ну а процедуры HandleFinally и HandleExcept дают ответ на вопрос, что собственно говоря, Delphi использует для обозначения "своих" исключений, как обрабатываются системные... Там ничего военного нет.
← →
Матлабист (2004-04-06 12:07) [9]Нафиг OR EAX, EAX ?
Флаги установить. В частности, ZF.
← →
Владислав © (2004-04-06 12:08) [10]> Fay © (06.04.04 11:41) [7]
Понятно, нафиг.OR EAX, EAX
JNE @@GoAhead
← →
Матлабист (2004-04-06 12:29) [11]При возникновении исключения, надо вызвать функцию API RaiseException. Передать ей код исключения, и прочие параметры. Я возьму реализацию с Delphi 5, потому как оная у меня
Win API SDK:VOID RaiseException(
DWORD dwExceptionCode, // exception code
DWORD dwExceptionFlags, // continuable exception flag
DWORD nNumberOfArguments, // number of arguments in array
CONST DWORD *lpArguments // address of array of arguments
);
System.pas, procedure _RaiseExcept;PUSH ESP { pass pointer to arguments }
PUSH 7 { there are seven arguments }
PUSH cNonContinuable { we can"t continue execution }
PUSH cDelphiException { our magic exception code }
PUSH EDX { pass the user"s return address }
JMP RaiseException
Итак, аргументы передаются в обратном порядке.PUSH EDX
JMP XXX
эквивалентен CALL XXX с адреса EDX. Т. е при выходе из RaiseException возврат бует произведен по адресу EDX.
cDelphiException єто dwExceptionCode
cNonContinuable єто dwExceptionFlags
7 єто nNumberOfArguments
ESP єто lpArguments
На данный момент ESP указывает на то, что было помещено в стек до этого. Смотрим что именно:PUSH ESP
PUSH EBP
PUSH EDI
PUSH ESI
PUSH EBX
PUSH EAX { pass class argument }
PUSH EDX { pass address argument }
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.035 c