Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi 10.4: Was kann einen Absturz bei der Auflösung von "MyObject as TType" verursachen ? (https://www.delphipraxis.net/204624-10-4-kann-einen-absturz-bei-der-aufloesung-von-myobject-ttype-verursachen.html)

Rollo62 12. Jun 2020 16:28

Delphi-Version: 10.4 Sydney

10.4: Was kann einen Absturz bei der Auflösung von "MyObject as TType" verursachen ?
 
Hallo zusammen,

ich teste gerade unter Rx10.4,
und ich habe einen seltsamen Crash unter iOS, das dürfe aber mit iOS nichts zu tun haben.

Der Code sieht so aus
Delphi-Quellcode:
procedure TMyListView.EvOnItemClickEx( const Sender: TObject;
                                            ItemIndex: Integer;
                                       const LocalClickPos: TPointF;
                                       const ItemObject: TListItemDrawable);
var
  LItemObject   : TListItemDrawable;

begin
    if Sender is TListView then
    begin

        LItemObject   := ItemObject;     //<=== das ist ein TListItemDrawable

        ...
 
        if Assigned( LItemObject ) then
        begin
            if LItemObject is TListItemText then //<=== hier crasht es, bei der Auflösung
            begin
                ...
            end
    ....
end;
dabei ist TListItemText von TListItemDrawable abgeleitet,
also sollte Obiges doch IMMER funktionieren.

Die Auflösung "as" stürzt hier ab (bei InheritsFrom)
Delphi-Quellcode:

function _IsClass(const Child: TObject; Parent: TClass): Boolean;
begin
  Result := (Child <> nil) and Child.InheritsFrom(Parent);
end;


class function TObject.InheritsFrom(AClass: TClass): Boolean;
var
  ClassPtr: Pointer;
  P: Pointer;
begin
  Result := False;
  ClassPtr := Pointer(Self);
  while True do
  begin
    if ClassPtr = Pointer(AClass) then
    begin
      Result := True;
      break;
    end;
    P := PPointer(PByte(ClassPtr) + vmtParent)^; //<=== hier crasht es, schon beim 1. Durchlauf
    if P = nil then break;
    ClassPtr := PPointer(P)^;
  end;
end;
Das Ganze passiert unter iOS, und ich kann die Pointer leider nicht vernünftig debuggen.

Der Aufruf kommt aus dem FMX.ListView, an dieser Stelle
Delphi-Quellcode:
procedure TListViewBase.ProcessIncident(const Entry: TDelayedIncidentEntry);
begin
  case Entry.Incident of
    TDelayedIncident.ChangeRepainted:
      DoChangeRepainted;

    TDelayedIncident.Invalidate:
      Invalidate;

    TDelayedIncident.SetItemIndex:
      SetItemIndexInternal(Entry.CustomData);

    TDelayedIncident.ClickEvent:
      if Assigned(FOnItemClickEx) then
        FOnItemClickEx(Self, FClickEventItemIndex, FClickEventMousePos, FClickEventControl); //<====

....
Die Parameter im ListView sollten doch eigentlich OK sein.
Könnte es was mit dem TDelayedIncident.ClickEvent zu tun haben ?

Bin im Moment ratlos was das sein könnte, vielleicht hat das schon mal jemand gelöst.

Das Ganze hat überigens unter Rx1033 (und vorher) wunderbar funktioniert.

Rollo62 16. Jun 2020 10:09

AW: 10.4: Was kann einen Absturz bei der Auflösung von "MyObject as TType" verursach
 
Push :oops: Gibt es hier denn gar keine Idee ?

Wie und warum kann das reproduzierbar bei der Auflösung der Typen crashen ?
Kann man das irgendwie besser Testen/Debuggen um zu sehen was los ist ?

Der OnItemClickEx Event müsste doch, wenn Assigned(), immer einen gültigen, auflösbaren Wert enthalten.

Sollte Assigned() das Problem sein, und muss warum auch immer <> nil benutzt werden ?

TiGü 16. Jun 2020 11:22

AW: 10.4: Was kann einen Absturz bei der Auflösung von "MyObject as TType" verursach
 
Log dir doch mal den Zeiger von LItemObject raus (mit IntToHex oder dergleichen).
Weil der Zeiger ist ja mit bspw. $1F ggf. assigned, aber es gibt keine gültige Datenstruktur dahinter.

Stevie 16. Jun 2020 11:50

AW: 10.4: Was kann einen Absturz bei der Auflösung von "MyObject as TType" verursach
 
Meine Vermutung ist, dass dadurch, dass das Event verzögert ausgeführt wird, in der Zwischenzeit das Objekt, was da übergeben wird, freigegeben wurde - vermutlich ein Bug, der sich beim entfernen von ARC auf iOS eingeschlichen hat - ich sehe, dass FClickEventControl mit [Weak] markiert ist, also unter ARC auf nil gesetzt wurde, wenn das Objekt dahinter freigegeben wurde, aber ohne ARC tut das gar nix. Da wird wohl irgendwo Code fehlen, der das nun auf nil setzt, sollte die Instanz, die dort referenziert werden, freigegeben werden.
Der ItemObject ist natürlich noch assigned/nicht nil, aber wenn du dann etwas damit machen willst (z.b. die Klasse überprüfen) klatscht das gegen die Wand. #danglingpointer

Rollo62 16. Jun 2020 12:40

AW: 10.4: Was kann einen Absturz bei der Auflösung von "MyObject as TType" verursach
 
Danke für die Vorschläge.

Ich habe auch das ARC im Verdacht.

Es passiert aber bei OnItemClickEx, und das FClickEventControl Feld wird gesetzt, also müsste das doch noch vorhanden sein.
Es scheint nur auf einer Stelle zu nil werden, da kommt der Debugger aber gar nicht vorbei.
Es wir ja nur durch Click nichts entfernt (normalerweise).

Ich muss mich wohl tiefer durch die iOS-Sourcen arbeiten.

Werde mir den Logger für die Pointer erweitern, gute Idee.

Weil ARC suspect erscheint werde ich das Ganze auch mal unter Android versuchen, statt mich in IOS festzubeissen.
Manchmal springt einem der Fehler dann sofort ins Auge.

Rollo62 17. Jun 2020 07:19

AW: 10.4: Was kann einen Absturz bei der Auflösung von "MyObject as TType" verursach
 
Ich habe die Stelle zusätzlich in try except finally verpackt, um das besser testen zu können.

Irgendwie spielt da aber auch immer der Debugger mit rein (unter iOS),
da bekomme ich teilweise ohne das ich irgendwas drücke immer mal Fehlermeldungen wie (sinngemäß)
"out of system resources",
"this current debug session must end before the requested operation can proceed. (terminate, detach, cancel, help)",
"in order to proceed you must close the debugger before",

Edit:
-->
Sowas steht in der Hilfe dazu
Zitat:

Your choices are:

Terminate closes the application that is running in the debugger and returns you to the IDE.
Detach disconnects the debugger from the current (running) program and refocuses on the IDE.
Cancel returns you to the debugger and allows you to terminate your application normally (for example, by selecting Close on the File menu).
Wobei Cancel durchaus normal weiter-debugged.
<--

Edit2:
-->
Ab und zu kommt auch diese Meldung, beim Deployment auf ein iOS Device, beim nächsten Mal geht es
dann wieder, oder auch nicht.
"Installed application lookup failed (attemp 1 of 5 in 5 sec.)"

Nach Löschen der App auf dem Gerät, und Build All geht es dann garantiert auch wieder.

Alle diese seltsamen Dinge habe ich vor 10.4 jedenfalls noch nie gesehen.
<--

Wenn ich die Meldungen wegklicke geht es aber trotzdem noch weiter.

Das Ganze ist dann ziemlich träge, was mich auf Fehler in Richtung LSP bringt.

Könnte es sein das der LSP, der jetzt ja auch im Debug-Mode funktioniert, nicht in einem parallelen Prozess sein Unwesen treibt, sondern auch im aktuellen Debug-Prozess ?`

So fühlt es sich jedenfalls an.

Ich werde mal versuchen CodeInsight ganz abzuschalten, oder auf den alten Mode.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:26 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