Ответ 1
Ну удар меня! Это выглядело так неправильно, что я должен был попробовать это сам, и ты абсолютно прав! Я сузил его до того, что это исключение ОС (деление на ноль), которое генерируется самой ОС, а не 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);
Удачи!