Хорошо, взорви меня!Это выглядело так неправильно, что я должен был попробовать это сам, и вы абсолютно правы!Я сузил это до того факта, что это исключение ОС (деление на ноль), которое генерируется самой ОС, а не Delphi.Если вы попытаетесь вызвать EIntError самостоятельно, вы получите ожидаемое поведение, а не то, что видите выше.Обратите внимание, что ожидаемое поведение возникает всякий раз, когда вы сами вызываете исключение.
Обновление: В модуле System.pas при повторном возникновении исключения вызывается следующий код:
{ Destroy any objects created for non-delphi exceptions }
MOV EAX,[EDX].TRaiseFrame.ExceptionRecord
AND [EAX].TExceptionRecord.ExceptionFlags,NOT cUnwinding
CMP [EAX].TExceptionRecord.ExceptionCode,cDelphiException
JE @@delphiException
MOV EAX,[EDX].TRaiseFrame.ExceptObject
CALL TObject.Free
CALL NotifyReRaise
Таким образом, если исключение не является исключением Delphi (в данном случае исключением ОС), исключение (измененное) Delphi освобождается, а исходное исключение повторно вызывается, тем самым отбрасывая любые изменения, внесенные висключение.Дело закрыто!
Обновление 2: (ничего не могу с собой поделать).Вы можете воспроизвести это с помощью следующего кода:
type
TThreadNameInfo = record
InfoType: LongWord; // must be $00001000
NamePtr: PAnsiChar; // pointer to message (in user address space)
ThreadId: LongWord; // thread id ($ffffffff indicates caller thread)
Flags: LongWord; // reserved for future use, must be zero
end;
var
lThreadNameInfo: TThreadNameInfo;
with lThreadNameInfo do begin
InfoType := $00001000;
NamePtr := PAnsiChar(AnsiString('Division by zero'));
ThreadId := $ffffffff;
Flags := $00000000;
end;
RaiseException($C0000094, 0, sizeof(lThreadNameInfo) div sizeof(LongWord), @lThreadNameInfo);
Веселитесь!