AGB  ·  Datenschutz  ·  Impressum  







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

RTTI-Bugs?

Ein Thema von himitsu · begonnen am 5. Mai 2014 · letzter Beitrag vom 8. Mai 2014
Antwort Antwort
Benutzerbild von himitsu
himitsu

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

RTTI-Bugs?

  Alt 5. Mai 2014, 09:07
Delphi-Version: XE5
Moin,

kennt jemand weitere Fehler in der RTTI?
  • falsche Daten bei Sets über 8 Byte (mehr als 64 Elemente)
    Das resultiert dann in falschen TypeSize in der RTTI
  • bei Array-Property (TRttiIndexedProperty) fehlt der Indexbezeichner, bzw. der wird direkt zum Index des Arrays gezählt, wobei aber der Wert dieser Angabe verloren geht.
    Das "wobei" erkennt man auch an dem Eintrag zum "Indexbezeichner" in der OH.
  • einige ToString-Methoden der RTTI, womit man die Deklaration (teilweise) abfragen kann, lösen gern Zugriffsverletzungen aus, wenn sie mit einem seltenern Sonderfall des Aufbaus zusammenstoßen, oder wenn nicht alle nötigen RTTI-Infos einkompiliert wurden.
    (nja, muß man das halt selber in Text übersetzen, was allerdings nicht immer so einfach ist, da nötige Basisfunktionen nicht öffentlich zugänglich sind ... zum Glück kann man da notfalls via RTTI ran, oder man kopiert die Funktionen, wenn man den Quellcde hat)


  • Enums mit manuellen Werten (type TMyEnum = (one, two=1, tree=7); ) fehlt in der die RTTI die Liste mit den Aufzählungswerten.
    Gut, das liegt vermutlich an der Art der Liste (#0-terminierte Stringliste), aber man hätte z.B. den fehlenden/übersprungenen Werten einen automatischen "Namen" verpassen können.
    (mein Vorschag wäre einfach eine Zahl, welche dem Wert entspricht, aber dieser "Fehler" existiert nun schon seit so vielen Jahrzehnten ... inzwischen ist das schon ein "Feature")


Vorallm der erste Punkt ist ein großes Problem, denn dort sind wirklich die grundlegenden RTTI-Rohdaten das Problem.
Außerdem wird ein Set, vorallem in der neuen RTTI, als "ordinaler" Typ behandelt, zusammen mit Enums, Integer und Chars, und das geht nunmal nur bis 8 Byte gut.
Die neue RTTI geht über TTypeData.OrdType, für die Größenbestimmung und da sind bei mehr als 8 Byte falsche/ungültige Werte enthalten.


Ein QC kommt demnächst. (erstmal sehn was sich noch für Fehler anfinden)



Meine Test-Daten, für den ersten Punkt:
Delphi-Quellcode:
type
  TMyEnum1 = 0..5; // 1 ... 8-1
  TMySet1 = set of TMyEnum1; // 1 Byte

  TMyEnum2 = 0..15; // 8 ... 16-1
  TMySet2 = set of TMyEnum2; // 2 Byte

  TMyEnum4 = 0..30; // 16 ... 32-1
  TMySet4 = set of TMyEnum4; // 4 Byte

  TMyEnum8 = 0..33; // 32 ... 64-1
  TMySet8 = set of TMyEnum8; // 8 Byte

  TMyEnum20 = 0..155; // ... 160-1
  TMySet20 = set of TMyEnum20; // 20 Byte

  TMyEnum32 = 0..250; // ... 256-1
  TMySet32 = set of TMyEnum32; // 32 Byte (multiple of 4)

  TMyEnum_1 = 0..$70;
  TMyEnum_2 = 0..$7F00;
  TMyEnum_4 = 0..$7FFF0000;
  TMyEnum_4u = 0..$FFFF0000;

  TMyClass = class abstract
    FField: Integer;
    FMyField1: TMySet1;
    FMyField2: TMySet2;
    FMyField4: TMySet4;
    FMyField8: TMySet8;
    FMyField32: TMySet32;
    FMyField_1: TMyEnum_1;
    FMyField_2: TMyEnum_2;
    FMyField_4: TMyEnum_4;
    FMyField_4u: TMyEnum_4u;
    function Getter(A, B: string; Index: Integer): TMySet4; virtual; abstract;
    procedure Setter(A, B: string; Index: Integer; Value: TMySet4); virtual; abstract;
    property X[A, B: string]: TMySet4 index 3 read Getter write Setter;
  published
    property I1: Integer index 1 read FField write FField default 3;
    property I2: Integer index 2 read FField write FField stored False ;
    property I3: Integer index 3 read FField write FField stored False default 3;
  end;
Und das, was man aus der RTTI auslesen kann: (als //-Kommentare sind die richtigen Werte enthalten, bzw. eine Erklärung)
Delphi-Quellcode:
// MinValue..MaxValue {TypeSize ClassName}

TMyEnum1 = {Integer}0..5; {Size=1 TRttiOrdinalType}

TMySet1 = set of TMyEnum1; {Size=1 OrdType=1=otUByte TRttiSetType}

TMyEnum2 = {Integer}0..15; {Size=1 TRttiOrdinalType}

TMySet2 = set of TMyEnum2; {Size=2 OrdType=3=otUWord TRttiSetType}

TMyEnum4 = {Integer}0..30; {Size=1 TRttiOrdinalType}

TMySet4 = set of TMyEnum4; {Size=4 OrdType=5=otULong TRttiSetType}

TMyEnum8 = {Integer}0..33; {Size=1 TRttiOrdinalType}

TMySet8 = set of TMyEnum8; {Size=1343671120 OrdType=255 TRttiSetType}
// SizeOf() = 8
// OrdType = invalid

TMyEnum20 = {Integer}0..155; {Size=1 TRttiOrdinalType}

TMySet20 = set of TMyEnum20; {Size=1 OrdType=1 TRttiSetType}
// SizeOf() = 20
// OrdType = invalid

TMyEnum32 = {Integer}0..250; {Size=1 TRttiOrdinalType}

TMySet32 = set of TMyEnum32; {Size=1 OrdType=1 TRttiSetType}
// SizeOf() = 32
// OrdType = invalid

TMyEnum_1 = {Integer}0..112; {Size=1 TRttiOrdinalType}

TMyEnum_2 = {Integer}0..32512; {Size=2 TRttiOrdinalType}

TMyEnum_4 = {Integer}0..2147418112; {Size=4 TRttiOrdinalType}

TMyEnum_4u = {Cardinal}0..-65536; {Size=4 TRttiOrdinalType}
// if MinValue > MaxValue then Cardinal

TMyClass = class {Package1.bpl Unit14.TMyClass Instance Size=4 TRttiInstanceType}
  public
    FField: Integer;
    FMyField1: TMySet1;
    FMyField2: TMySet2;
    FMyField4: TMySet4;
    FMyField8: TMySet8;
    FMyField32: TMySet32;
    FMyField_1: TMyEnum_1;
    FMyField_2: TMyEnum_2;
    FMyField_4: TMyEnum_4;
    FMyField_4u: TMyEnum_4u;
    function Getter(A: string; B: string; Index: Integer): TMySet4; virtual; {Index=0 Addr=$237B23D8}
    procedure Setter(A: string; B: string; Index: Integer; Value: TMySet4); virtual; {Index=1 Addr=$237B23E0}
    property X[A: string; B: string; Index: Integer]: TMySet4 read _Getter write _Setter;
    // TRttiIndexedProperty.ToString liefert für "X" nur eine "Zugriffsverletzung bei Adresse 6F687465. Lesen von Adresse 6F687465"
    // es sollte eigentlich "property X[A: string; B: string; Index: Integer]: TMySet4" liefern, was aber nicht am Set liegt
  published
    // für die Namen der Setter/Getter hab ich noch keine Übersetztung eingeaut
    property I1: Integer index 1 read _Field0004 write _Field0004 default 3;
    property I2: Integer index 2 read _Field0004 write _Field0004;
    property I3: Integer index 3 read _Field0004 write _Field0004 default 3;
  end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 5. Mai 2014 um 09:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#2

AW: RTTI-Bugs?

  Alt 5. Mai 2014, 09:12
Was mir seit langem übel aufstößt ist fehlende komplette RTTI für Records und dort insbesondere die "alten" strings.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: RTTI-Bugs?

  Alt 5. Mai 2014, 09:27
In der alten RTTI?
Published-Felder sollten aber dennoch vorhanden sein. (published gibt es im Record nicht)


In der neuen "erweiterten RTTI" sind die eigentlich vorhaden. (siehe der Anhang in http://www.delphipraxis.net/180247-r...fahrungen.html)


[add]
Delphi-Quellcode:
type
  TMyRecord = record
    A: Byte;
    B: Integer;
    C: ShortString;
    D: string[3];
    E: string;
    property F: Integer read B;
    procedure G;
  end;
Und über die RTTI generiert:
Delphi-Quellcode:
TMyRecord = record {Package1.bpl Unit14.TMyRecord Managed Record Size=272 TRttiRecordType}
  public
    { 0} A: Byte;
    { 4} B: Integer;
    { 8} C: ShortString;
    {264} D: {unknown};
    {268} E: string;
    procedure G; {Addr=$26B37698}
  end;
Warum gerade der eine ShortString mit Längenangabe nicht geht, müsste ich nochmal prüfen. (mir war so, als gingen die)


[add2]
OK, das Problem besteht erstmal nur bei eingebettenten Strings.
Delphi-Quellcode:
type
  TMyStr = string[3];
  TMyRecord = record
    A: Byte;
    B: Integer;
    C: ShortString;
    D: TMyStr;
    E: string;
    property F: Integer read B;
    procedure G;
  end;
Delphi-Quellcode:
TMyStr = string[3]; {Package1.bpl Unit14.TMyStr Size=4 TRttiStringType}

TMyRecord = record {Package1.bpl Unit14.TMyRecord Managed Record Size=272 TRttiRecordType}
  public
    { 0} A: Byte;
    { 4} B: Integer;
    { 8} C: ShortString;
    {264} D: TMyStr;
    {268} E: string;
    procedure G; {Addr=$23AC7684}
  end;
Dabei fällt mir ein, daß es auch ein Problem mit Sets gab.
set of TEnum geht, aber bei set of (one, two, tree); knallt es oftmals.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 5. Mai 2014 um 09:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: RTTI-Bugs?

  Alt 8. Mai 2014, 08:26
Nur damit die Begrifflichkeiten nicht irreführen:
Es gibt keine alte und neue RTTI, es gibt nur eine RTTI. Das Zeugs in der Rtti.pas greift nach wie vor auf die Strukturen in der TypInfo.pas zu. Was neu ist, ist, dass die vom Compiler generierten Informationen erweitert wurden (in Bezug auf nicht published Member, Attribute etc). Aber auch die könnte man, wenn man mutig genug ist, nur mit der TypInfo.pas auslesen.

Außerdem kannst du dir mind einen QC Eintrag sparen, denn die indexed Property wird unter XE6 korrekt ausgegeben.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie ( 8. Mai 2014 um 08:34 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: RTTI-Bugs?

  Alt 8. Mai 2014, 11:24
Die Struktur der RTTI wurde erweitert und es stehen jetzt standardmäßig zu mehr Dingen Daten darin, welche es früher nicht gab, wie z.B. private Felder.
Viele der neuen Infos werden von den TRtti-Klassen direkt aus den Record-Strukturen gelesen, ohne daß es da neue Ausleseprozeduren in der TypInfo dafür gibt.
Und es gibt die neuen OOP-mäßige Klassenstruktur, zum Auflisten der Daten.

Mindestens 3 Exceptions gab es in XE6 auch noch, beim Auflisten der kompletten RTTI eines gewissen Programmes,
aber ich weiß jetzt auf die Schnelle nicht, welche das waren. (zumindestens waren es weniger, als im XE3)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  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 11:51 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