AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Access Violation in TObject.InheritsFrom von "is"-Operator
Thema durchsuchen
Ansicht
Themen-Optionen

Access Violation in TObject.InheritsFrom von "is"-Operator

Ein Thema von AuronTLG · begonnen am 5. Jul 2024 · letzter Beitrag vom 5. Jul 2024
Antwort Antwort
AuronTLG

Registriert seit: 2. Mai 2018
Ort: Marburg
291 Beiträge
 
Delphi 12 Athens
 
#1

Access Violation in TObject.InheritsFrom von "is"-Operator

  Alt 5. Jul 2024, 09:53
Moin,

ich habe hier gerade ein seltsames Problem, bei dem ich mal nachfragen wollte, ob das jemandem was sagt:
Ich hatte in Verbindung mit einer TMS-Komponente eine Zugriffsverletzung und hatte denen das mit einem sehr einfachen Testprojekt mitgeteilt. Dummerweise tritt bei denen das Problem partout nicht auf, was eine Lösung erschwert.

Debuggen liefert folgendes:
Die auslösende Codezeile ist eine einfache Klassenüberprüfung im Format "If (XYZ is TIchBinEineKlasse)". Von da aus geht es nach "System._IsClass" und von da aus zuguterletzt nach "System.TObject.InheritsFrom", wo es dann in der Codezeile "P := PPointer(@PByte(P)[vmtParent])^;" knallt.
Bevor es knallt ist das Programm aber schon einmal über besagte auslösende Codestelle problemlos drübergelaufen.
Und nur um das das Offensichtliche auszuschließen: "XYZ" ist kein Nullpointer.

Dementsprechend habe ich zwei Merkwürdigkeiten:

1. Dass es bei der Nutzung vom is-Operator überhaupt knallen kann. Es ist ja nicht so dass man dabei irgendwas falsch machen könnte.
2. Dass es nur bei mir auftritt. Wobei ich es sicherheitshalber auch nochmal auf einem anderen PC mit komplett eigener Kompilierung ebenfalls reproduzieren konnte.

Ich habe die neuste Delphi Version mit Patch, das neuste Windows 11, die neuste Komponentenversion und das Projekt in dem ich es reproduziere ist ein absolut jungfräuliches und minimalistisches Projekt ohne irgendwelche Einstellungsänderungen etc, d.h. auch da kann nichts schieflaufen. Ich kann mir auch nicht vorstellen, dass das irgendwie an einer allgemeinen Delphi-Einstellung hängen sollte, will es aber auch nicht ausschließen.

Hat irgendwer sowas schonmal gehabt?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Access Violation in TObject.InheritsFrom von "is"-Operator

  Alt 5. Jul 2024, 10:04
Eine Möglichkeit ist, dass im Speicher etwas nicht in Ordnung ist, weil an anderer Stelle Speicher überschrieben wurde. Letzlich bleibt in solch einem Fall nur, den Speicherinhalt zu prüfen. Da sich die VMT nach dem ersten erfolgreichen Aufruf nicht ändern sollte, ist das in dem Fall überschaubar. Da kannst du den Speicherbereich vorher und nachher anschauen. Du kannst da auch mit Datenhaltepunkten arbeiten, damit du Änderungen mitbekommst.

Schlimmer ist es, wenn das nur in einem echten großen Projekt auftritt...
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.623 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Access Violation in TObject.InheritsFrom von "is"-Operator

  Alt 5. Jul 2024, 10:13
Und nur um das das Offensichtliche auszuschließen: "XYZ" ist kein Nullpointer.

Dementsprechend habe ich zwei Merkwürdigkeiten:

1. Dass es bei der Nutzung vom is-Operator überhaupt knallen kann. Es ist ja nicht so dass man dabei irgendwas falsch machen könnte.
2. Dass es nur bei mir auftritt. Wobei ich es sicherheitshalber auch nochmal auf einem anderen PC mit komplett eigener Kompilierung ebenfalls reproduzieren konnte.
Dass es kein NIL-Pointer ist, heißt nicht, dass es ein Pointer auf ein gültiges Objekt ist.

Folgendes knallt auch:
Delphi-Quellcode:
var
  SomeObj: TSomeClass;
begin
  SomeObj := Pointer(5);
  if SomeObj = nil then
    raise Exception.Create('SomeObj ist nil');
  if not (SomeObj is TSomeClass) then
    raise Exception.Create('SomeObj ist kein TSomeClass');
end;
Da $00000005 kein Pointer auf ein TObject ist, knallt es hier auch schon beim Ausführen des IS-Operators.

So einfach wird es in Deinem Fall aber wohl nicht sein, sondern eher sowas wie:

Delphi-Quellcode:

procedure DoSomething(var _Obj: TSomeClass);
begin
  _Obj.Free;
end;

var
  SomeObj: TSomeClass;
begin
  SomeObj := TSomeClass.Create;
  DoSomething(SomeObj);
  if SomeObj = nil then
    raise Exception.Create('SomeObj ist nil');
  if not (SomeObj is TSomeClass) then
    raise Exception.Create('SomeObj ist kein TSomeClass');
end;
Der Pointer zeigt nach Aufruf von DoSomething auf eine inzwischen freigegebene Instanz von TSomeClass. Je nachdem, ob der davon benutzte Speicher in der Zwischenzeit anderweitig verwendet wurde oder nicht, wird der IS-Operator fehlschlagen oder nicht. Ob das der Fall ist, kann von vielen Bedingungen abhängen. Und es kann sein, dass es auf einem Rechner zu einem Fehler führt und auf einem anderen nicht.

Es gibt auch noch andere Möglichkeiten (z.B. irgendwas übeschreibt den Pinter), aber ich dieser Fall ist der wahrscheinlichste.
Thomas Mueller
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Access Violation in TObject.InheritsFrom von "is"-Operator

  Alt 5. Jul 2024, 10:16
Der Zugriff auf eine freigegebene Instanz kann mit FastMM sehr einfach erkannt werden. Bei einem einfachen Testprojekt sollte das aber normalerweise auch so auffallen.

Kannst du das Testprojekt hier zeigen?
Sebastian Jänicke
AppCentral

Geändert von jaenicke ( 5. Jul 2024 um 10:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Access Violation in TObject.InheritsFrom von "is"-Operator

  Alt 5. Jul 2024, 10:20
Während dieses Aufrufs wird der Speicher dort wohl nicht kaputt geh.

Es ist wohl eher so, dass es
* einfach ein ungültiger Zeiger ist -> Variable nicht initialisiert oder Objekt schon freigegeben, auf welches dort gezeigt wird
* oder es gab irgendwo z.B. einen Bufferoverflow und hat dir da was zerschossen.


Zu einem Zeitpunkt, wo es noch geht, müsstest du also anfangen und könntest dir dann die Speicher ansehen,
also die Stelle der Variable, bzw. den Inhalt des Objektes
* ganz am Anfang (Offset 0) steckt der Zeiger zur Klasse
* und dann in den Typinfos selbst, geht es dann weiter (vmtParent), da dort ja auch die Vorfahren geprüft werden

Das dann mit dem Zeitpunkt vergleichen, wenn es knallt,
und jetzt oder schon vorher prophylaktisch via Datenhaltepunkten, Guards oder ab und an manuell nachsehn, wann und durch wen es sich ändert.


Joar, das große FastMM im Debugmodus, Deleaker, Erekalog, madExcept und andere Tools können eventuell helfen.




"Testprojekt" oder selbst testen, also versuchen das im Kleinen nachzustellen,
bzw. das Projekt so lange ausmisten, bis der Fehler weg ist ... das zuletzt entfernte Codestück ist dann schonmal ein Anfang zum Suchen.



PS: Auch wenn es keine "wirkliche" Lösung ist, aber geh mal in Projektoptionen > Erzeugen > Delphi-Compiler > Linken > und schalte die beiden Optionen bezüglich ASLR ab .... ist der Fehler dann weg?
$2B or not $2B

Geändert von himitsu ( 5. Jul 2024 um 10:27 Uhr)
  Mit Zitat antworten Zitat
AuronTLG

Registriert seit: 2. Mai 2018
Ort: Marburg
291 Beiträge
 
Delphi 12 Athens
 
#6

AW: Access Violation in TObject.InheritsFrom von "is"-Operator

  Alt 5. Jul 2024, 10:42
Zitat:
PS: Auch wenn es keine "wirkliche" Lösung ist, aber geh mal in Projektoptionen > Erzeugen > Delphi-Compiler > Linken > und schalte die beiden Optionen bezüglich ASLR ab .... ist der Fehler dann weg?
Nur schonmal schnelle Rückmeldung: Ohne ASLR-Unterstützung funktioniert es.
Ich schaue mir das Ganze genauer an, aber das ist schonmal ziemlich hilfreich zur Eingrenzung, danke.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Access Violation in TObject.InheritsFrom von "is"-Operator

  Alt 5. Jul 2024, 11:19
Eingrenzung nicht direkt.
ASLR sorgt ja nur dafür, dass DLLs und Speicheranforderungen mehr zufälliger verteilt werden.
z.B. auch DLLs in verschiedenen Prozessen nicht an der selben stelle liegen (wurde früher gern gemacht, damit Windows "identische" Teile des Speicher gemeinsam verwenden kann, bzw. z.B. Reallocationen nicht jedes mal neu berechnen muß, wenn im nächsten Prozess die selbe DLL geladen wird)

Wenn aber nun jemand mit statischen/hartcodierten Zeigern arbeitet, dann knallt es ... bzw. damit auch Hacker/Viren/Trojaner/usw. es schwerer haben.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz