AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Interface problem/crash

Ein Thema von TurboMagic · begonnen am 20. Aug 2021 · letzter Beitrag vom 23. Aug 2021
Antwort Antwort
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.942 Beiträge
 
Delphi 12 Athens
 
#1

Interface problem/crash

  Alt 20. Aug 2021, 16:54
Hallo,

in einer Android App habe ich seit Umstellung auf 10.4.x ein Problem mit einem Crash.
Dank Debugger bin ich ein wenig weiter.

Es gibt in der App ein selber geschriebenes Interface und dessen Referenz soll
an einen Konstruktor einer Klasse übergeben werden die von TThread abstammt.

Kommt man das erste Mal da vorbei ist noch alles gut und die App tut was sie soll.
Kommt man später wieder dran vorbei und der RefCount im Interface scheint 0.

Kommt man später wieder an die Stelle knallt es bei der Übergabe des Interfaces
und wenn man sich direkt davor den RefCount anschaut, ist der total verbogen.
Astronomisch hoch oder auch negativ.

Die einzige Stelle, an der ein Free auf das Feld, welches dieses Interface
bereit stellt gemacht wird (ja, soll man nicht), wird lt. Debugger nicht
angesprungen.

Woran kann es noch liegen?

Grüße
TurboMagic
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

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

AW: Interface problem/crash

  Alt 20. Aug 2021, 17:49
Bei einer eigenen Klasse, die das Interface implementiert, ist das sehr einfach:
Überschreibe einfach _Release und setze dort einen Haltepunkt.

Eine mögliche Ursache:
Du übergibst ein Objekt direkt über den Aufruf des Konstruktors als konstanten Parameter.
Delphi-Quellcode:
procedure Blub(const AData: IInterface);
...
Blub(TMyClass.Create);
An der Stelle funktioniert die Referenzzählung nicht korrekt, weshalb man die Instanz immer zuerst in eine Interfacevariable speichern muss. Diese Variable kann man dann an die Methode übergeben:
Delphi-Quellcode:
Test := TMyClass.Create;
Blub(Test);
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.942 Beiträge
 
Delphi 12 Athens
 
#3

AW: Interface problem/crash

  Alt 20. Aug 2021, 21:47
Danke, das sind schon mal 2 verfolgenswerte Ansätze.
Was mich etwas wundert ist halt, dass es unter 10.3.3 noch funktionierte.
Aber da ich nicht genau weiß, wass seit dem alles wegen ARC Ablösung
geändert wurde versuche ich es erstmal mit den Ansätzen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Interface problem/crash

  Alt 20. Aug 2021, 23:06
ARC wurde doch in den letzten Delphis nochmal umgebaut?

Aber egal, hier geht es eh nicht um ARC, da die Referenzzählung bei den Interfaces überall gleich ist.


Willst du das dennoch als Einzeiler haben, dann bau dir ein eigenes "Create", welches als "class function" direkt das IInterface bzw. IMyClass zurück gibt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.942 Beiträge
 
Delphi 12 Athens
 
#5

AW: Interface problem/crash

  Alt 22. Aug 2021, 15:26
Bei einer eigenen Klasse, die das Interface implementiert, ist das sehr einfach:
Überschreibe einfach _Release und setze dort einen Haltepunkt.

Eine mögliche Ursache:
Du übergibst ein Objekt direkt über den Aufruf des Konstruktors als konstanten Parameter.
Delphi-Quellcode:
procedure Blub(const AData: IInterface);
...
Blub(TMyClass.Create);
An der Stelle funktioniert die Referenzzählung nicht korrekt, weshalb man die Instanz immer zuerst in eine Interfacevariable speichern muss. Diese Variable kann man dann an die Methode übergeben:
Delphi-Quellcode:
Test := TMyClass.Create;
Blub(Test);
Habe ein wenig damit rumgespielt und folgendes ermittelt:

1. Habe _AddRef und _Release beide überschrieben und darin sowohl einen Breakpoint gesetzt als auch
eine LogCat Logmeldung ausgegeben
2. Beide werden nie aufgerufen
3. Es gibt eine Klasse, die hat ein Feld von der Klasse die das Interface implementiert.
Dem Feld wird mittels <Klassenname>.Create(...); die Objektreferenz zugewiesen und dieses Feld
wird später an den Constructor des Threads übergeben (genauer: das Property davon, welches direkt
auf das Feld durchgreift).

Was nun? Das Interface deckt bisher leider nicht die komplette Funktionalität der Klasse ab.
Man könnte es ggf. erweitern und dann statt einer normalen Objektreferenz für das Feld gleich das
Interface benutzen. Würde das die Sache besser machen?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

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

AW: Interface problem/crash

  Alt 22. Aug 2021, 15:53
3. Es gibt eine Klasse, die hat ein Feld von der Klasse die das Interface implementiert.
Dem Feld wird mittels <Klassenname>.Create(...); die Objektreferenz zugewiesen und dieses Feld
wird später an den Constructor des Threads übergeben (genauer: das Property davon, welches direkt
auf das Feld durchgreift).
Wenn du die Instanz in einer Objektreferenz speicherst, darfst du entweder nie (!) das Interface verwenden oder du musst die Referenzzählung in der Klasse deaktivieren (sprich statt TInterfaceObject als Basisklasse einfach TSingletonImplementation aus System.Generics.Defaults verwenden).

Was nun? Das Interface deckt bisher leider nicht die komplette Funktionalität der Klasse ab.
Man könnte es ggf. erweitern und dann statt einer normalen Objektreferenz für das Feld gleich das
Interface benutzen. Würde das die Sache besser machen?
Ja, eindeutig. Du kannst auch ein zweites Interface dafür verwenden und mit as / Supports casten, wenn diese Funktionalität nicht offen verfügbar sein soll.

Man kann eine Instanz einer Klasse nach der Erstellung auch durchaus in eine Objektreferenz packen und z.B. mit Daten füttern und erst danach in eine Interfacereferenz packen, die diese Möglichkeiten nicht bietet. Aber danach darf man die Objektreferenz nie wieder verwenden (am besten direkt auf nil setzen), da man ja nie weiß wann das Objekt über das Interface freigegeben wird (wodurch das Objekt aus der Objektreferenz ungültig ist). Außerdem wird das Objekt freigegeben, sobald das Objekt als Interface weitergegeben wurde und die Interfacereferenzen aus dem Scope laufen oder nil werden. Denn es gibt ja keine dauerhaft aktive Interfacereferenz, wenn es als Objektreferenz gespeichert wird...

1. Habe _AddRef und _Release beide überschrieben und darin sowohl einen Breakpoint gesetzt als auch
eine LogCat Logmeldung ausgegeben
Das verstehe ich bei Verwendung des Interfaces nicht. Aber ohne Quelltext kann ich dazu auch nicht viel mehr sagen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.942 Beiträge
 
Delphi 12 Athens
 
#7

AW: Interface problem/crash

  Alt 22. Aug 2021, 16:59
Nach Umstellung der implementierenden Klasse auf TSingletonImplementation sehen die ersten Tests gut aus.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

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

AW: Interface problem/crash

  Alt 22. Aug 2021, 18:29
Du solltest dann nur nicht die von dir erwähnte Freigabe mit Free am Ende (im Destruktor der Klasse, in der sich das Feld befindet) vergessen. Ohne Referenzzählung funktionieren die Instanzen ja wie einfache Objekte und müssen entsprechend auch normal freigegeben werden.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.942 Beiträge
 
Delphi 12 Athens
 
#9

AW: Interface problem/crash

  Alt 23. Aug 2021, 07:57
Du solltest dann nur nicht die von dir erwähnte Freigabe mit Free am Ende (im Destruktor der Klasse, in der sich das Feld befindet) vergessen. Ohne Referenzzählung funktionieren die Instanzen ja wie einfache Objekte und müssen entsprechend auch normal freigegeben werden.
Recht hast du, da hab' ich aber selber schon dran gedackt. Danke!
  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 07:24 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