Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.049 Beiträge
 
Delphi 12 Athens
 
#12

AW: Exception - Register + DataStack

  Alt 24. Mai 2022, 08:45
Wenn man mit richtigen Delphi-Exceptions arbeitet, dann erstellt man ja oft auch erst kurz vorher noch das Exception-Object
und beim Erstellen eines Objektes und dem zusammenbauen von Strings, läuft genug ab, um Alles zu verändern.

Ausnahme, man macht es wie beim EOutOfMemory, wo das Objekt bereits vorher erstellt wurde (klar, weil ja praktisch der RAM schon voll ist und kein Speicher mehr zum Erstellen frei sein könnte)
und braucht dann "nur" noch das Raise , womit aber dennoch mindestens ein EAX verändert wird, um das Objekt zu übergeben.



Bleiben also nur noch die OS-Exceptions, wie AccessViolation oder DivisionByZero, was man nahezu direkt auslösen könnte.
Beim Letztem wird zwar oft auch mit mindestens einem Wert in den Registern gerechnet, aber da könnte man "irgendwas" nehmen, war grade in den Registern steht und die NULL kommt vom Heap/Stack.

Aber auch hier wieder das Problem, dass im ExceptionRecord von Windows keine Register drin sind und man somit auch erst wieder Code in der Fehlerbehandlung braucht, um die Register auszulesen,
was nur ginge, wenn das in einem anderen Thread passiert.

Delphi-Quellcode:
  EExternal = class(Exception)
  public
    {$IFDEF MSWINDOWS}
    ExceptionRecord: PExceptionRecord platform; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
    {$ENDIF}
    {$IF defined(LINUX) or defined(MACOS) or defined(ANDROID)}
    ExceptionAddress: LongWord platform;
    AccessAddress: LongWord platform;
    SignalNumber: Integer platform;
    {$ENDIF}
  end;

  EExternalException = class(EExternal);

  EIntError = class(EExternal);
  EDivByZero = class(EIntError);
  ERangeError = class(EIntError);
  EIntOverflow = class(EIntError);

  EMathError = class(EExternal);
  EInvalidOp = class(EMathError);
  EZeroDivide = class(EMathError);
  EOverflow = class(EMathError);
  EUnderflow = class(EMathError);

  EAccessViolation = class(EExternal); <<<<<<<<<<<<<
  EPrivilege = class(EExternal);
  EStackOverflow = class(EExternal) end deprecated;
  EControlC = class(EExternal);
Delphi-Quellcode:
  try
    ...
    Pointer(nil) := 666;
  except
    on E: Exception do begin
      // für GetThreadContext wäre es hier schon zu spät
      // aber E.ExceptionRecord wäre aber noch verfügbar
    end;
  end;
Noch etwas früher kommt man in die Fehlerbehandlung rein, wenn man die Registrierungsstellen in Exception/SysUtils/System benutzt,
aber auch da wird vorher immer noch etwas Code ausgeführt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (24. Mai 2022 um 11:40 Uhr)
  Mit Zitat antworten Zitat