TBufDataset: External ACCESS VIOLATION

Rund um die LCL und andere Komponenten
Antworten
Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

TBufDataset: External ACCESS VIOLATION

Beitrag von Geronimo »

Moin,

ich lese mit einem BufDataset eine xml-Datei ein.

Code: Alles auswählen

LoadFromFile(DBPfad+DBName_ProfileEN,dfXML)
Meistens funktioniert es, aber gelegentlich kommt eine böse Fehlermeldung:

"Exception-Klasse »External: ACCESS VIOLATION« ausgelöst mit der Meldung:
Access violation reading from address $0000000001401000."

Ich habe keine Idee, wie ich das Problem lösen soll.

Der Assember wirft so was aus:
"BUFDATASET$_$TCUSTOMBUFDATASET_$__$$_SETFIELDDATA$TFIELD$POINTER$BOOLEAN+33"

Hat jemand eine Idee, wie ich den Fehler finden kann?
Es ist immer die selbe Adresse.
Es muss irgendwie mit der xml-Datei zusammenhängen, mit einem Boolean Feld.
Kann in der xml-Datei aber nichts Böses entdecken, zumal das BufDataset die Datei per saveToFile selbst erzeugt hat.
:cry:

Edit: Testprojekt angehängt.
BufDataset-Test.zip
(464.14 KiB) 20-mal heruntergeladen
Zuletzt geändert von Geronimo am Fr 4. Apr 2025, 21:34, insgesamt 1-mal geändert.
Die Welt ist linear, rechteckig und gaussverteilt.

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von Zvoni »

Kannst mal den bösen code hier reinhängen?

EDIT: Hat nix mit dem Boolean zu tun
Hab mir den Quellcode für SetFieldData angeschaut, und das BOOLEAN in deiner assembler-Meldung ist irreführend (überladene Funktion, das Boolean wird beim Weiterleiten ignoriert)

Meine Vermutung ist eher, dass mit dem Buffer (der POINTER) was nicht stimmt, weil eine AV eine Zugriffsverletzung ist ("Ich will was von der Adresse..... Nö, is nich!")

Frage: Heist du dem OnValidate des TField ein Event zugeordnet?
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von Geronimo »

Moin Zvoni,
danke für die Rückmeldung.
Frage: Hast du dem OnValidate des TField ein Event zugeordnet?
Nein. Hätte ich das tun sollen?

Wenn es nur gelegentlich auftritt, muss es m.E. ja ein Timing-, sprich, Synchronisationsproblem sein.

Den Code extrahiere ich aus meinem Projekt in ein Beispielprojekt und poste ihn.
(Muss jetzt aber erst mal auf Arbeit.)

Grüße aus Hamburg
Die Welt ist linear, rechteckig und gaussverteilt.

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von Zvoni »

Geronimo hat geschrieben: Fr 4. Apr 2025, 08:49 Moin Zvoni,
danke für die Rückmeldung.
Frage: Hast du dem OnValidate des TField ein Event zugeordnet?
Nein. Hätte ich das tun sollen?
Nein, nicht unbedingt. Habe im Quelltext eben gesehen, dass in OnValidate (Falls der Event zugewiesen ist) der Buffer weitergegeben wird, und es eben da halt auch knallen kann.

Eine AV in Zusammenhang mit einem Pointer ist in der Regel der Versuch einen "ungültigen" Zeiger zu dereferenzieren.

EDIT: Nicht nur den Code, eventuell auch deine XML-Datei (oder welches Format das Ding auch hat) hier reinhängen.
Vielleicht ist es ja eine NULL
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

charlytango
Beiträge: 1058
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von charlytango »

Geronimo hat geschrieben: Fr 4. Apr 2025, 01:17 ich lese mit einem BufDataset eine xml-Datei ein.

LoadFromFile(DBPfad+DBName_ProfileEN,dfXML)

Meistens funktioniert es, aber gelegentlich kommt eine böse Fehlermeldung:
nur mal so quergedacht...
Wenn Problem gelegentlich auftritt und es mit Dateifunktionen zu tun hat, denke ich erst einmal an Probleme mit dem Dateisystem. Kann es sein dass, die Datei aus der du lesen willst irgendwie gesperrt ist?

Benutzeravatar
Zvoni
Beiträge: 363
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von Zvoni »

charlytango hat geschrieben: Fr 4. Apr 2025, 09:57
Geronimo hat geschrieben: Fr 4. Apr 2025, 01:17 ich lese mit einem BufDataset eine xml-Datei ein.

LoadFromFile(DBPfad+DBName_ProfileEN,dfXML)

Meistens funktioniert es, aber gelegentlich kommt eine böse Fehlermeldung:
nur mal so quergedacht...
Wenn Problem gelegentlich auftritt und es mit Dateifunktionen zu tun hat, denke ich erst einmal an Probleme mit dem Dateisystem. Kann es sein dass, die Datei aus der du lesen willst irgendwie gesperrt ist?
Im Lesen-Modus? (LoadFromFile)
Wie soll ne XML-Datei, welche ja stumpfer text ist, zum Lesen gesperrt sein?
gibts überhaupt ein DenyRead oder wie das heisst, wo so ne Datei im Code vorher geöffnet sein könnte?
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von Geronimo »

@charlytango,
Wenn Problem gelegentlich auftritt und es mit Dateifunktionen zu tun hat, denke ich erst einmal an Probleme mit dem Dateisystem. Kann es sein dass, die Datei aus der du lesen willst irgendwie gesperrt ist?
An sowas ähnliches hatte ich auch schon gedacht. Hatte Windof mit seinem Defender in Verdacht. So nach dem Motto: xml darf nur mit Edge geöffnet werden, sonst verdächtig.
Ist aber nicht. Die xml liegt im gleichen Verzeichnis wie das ganze Projekt. Mit den anderen xml-Dateien (Ist ja nicht die einzige.) funktioniert ja auch alles.
Anfänglich ist das Problem auch nicht aufgetreten.
Ich denke schon, dass es etwas mit der Datei und dem BufDataset (oder dem Packetreader) zu tun hast.
Die Welt ist linear, rechteckig und gaussverteilt.

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von Geronimo »

Moin Zvoni,

habe Testprojekt im ersten Beitrag angehängt.
Ich kann damit den Fehler reproduzieren. Die Adresse ist immer noch die gleiche.
Nicht nur den Code, eventuell auch deine XML-Datei (oder welches Format das Ding auch hat) hier reinhängen.
Ist schon klar. Ohne die XML-Datei wirst du nichts.

Bin dann mal für eine Woche weg (Urlaub 8) ).

Danke schon mal im Voraus.
Die Welt ist linear, rechteckig und gaussverteilt.

wp_xyz
Beiträge: 5129
Registriert: Fr 8. Apr 2011, 09:01

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von wp_xyz »

Habe mir mal die xml-Datei angesehen, und da fällt mir das AUTOINC auf. Ich weiß das nie: du willst ein AutoInc-Field mit Werten aus einer Datei neu beschreiben. Geht das überhaupt? Das AutoInc wird doch vom Datenbank-System vorgegeben.

Ich habe einfach mal im MetaData-Abschnitt das AutoInc-Feld ID zu einem einfachen Integer abgeändert - und nun lädt die Datei problemlos. Es ist der erste <FIELD> Eintrag:

Code: Alles auswählen

<?xml version="1.0" encoding="utf-8"?>
<DATAPACKET Version="2.0">
  <METADATA>
    <FIELDS>
      <FIELD attrname="ID" fieldname="ID" fieldtype="i4"/>
      <FIELD width="100" attrname="Bezeichnung" fieldname="Bezeichnung" fieldtype="string"/>
      <FIELD width="100" attrname="Hersteller" fieldname="Hersteller" fieldtype="string"/>
      <FIELD attrname="A" fieldname="A" fieldtype="r8"/>
      <FIELD attrname="I" fieldname="I" fieldtype="r8"/>
      <FIELD attrname="Wel" fieldname="Wel" fieldtype="r8"/>
      <FIELD attrname="Wpl" fieldname="Wpl" fieldtype="r8"/>
      <FIELD attrname="tf" fieldname="tf" fieldtype="r8"/>
      <FIELD attrname="tw" fieldname="tw" fieldtype="r8"/>
      <FIELD attrname="h" fieldname="h" fieldtype="r8"/>
      <FIELD attrname="b" fieldname="b" fieldtype="r8"/>
      <FIELD attrname="alpha" fieldname="alpha" fieldtype="r8"/>
      <FIELD attrname="bf" fieldname="bf" fieldtype="r8"/>
      <FIELD attrname="m" fieldname="m" fieldtype="r8"/>
      <FIELD attrname="SA" fieldname="SA" fieldtype="boolean"/>
      <FIELD width="100000" attrname="Grafik" fieldname="Grafik" fieldtype="string"/>
      <FIELD attrname="U" fieldname="U" fieldtype="r8"/>
      <FIELD attrname="Apf" fieldname="Apf" fieldtype="r8"/>
      <FIELD attrname="Upf" fieldname="Upf" fieldtype="r8"/>
    </FIELDS>
  </METADATA>
Im nächsten Schritt habe ich mir selbst ein kleines Test-Programm geschrieben, das einen BufDataset mit AutoInc-ID erzeugt und als xml abspeichert:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  F: TField;
begin
  if not FileExists(FILE_NAME) then
  begin
    BufDataset1.FieldDefs.Add('ID', ftAutoInc);
    BufDataset1.FieldDefs.Add('INTVALUE', ftInteger);
    BufDataset1.FieldDefs.Add('DATEVALUE', ftDate);
    BufDataset1.FieldDefs.Add('FLOATVALUE', ftFloat);
    BufDataset1.CreateDataset;
    BufDataset1.Open;
    for i := 0 to 100 do
      BufDataset1.AppendRecord([
        Random(100),
        Random(365) + EncodeDate(2020, 1, 1),
        Random *1000
      ]);
  end else
    BufDataset1.LoadFromFile(FILE_NAME, dfXML);
end; 
Seltsam: diese Datei lädt ohne Fehler, und hat aber dieselbe AUTOINC-Zeile, wie deine Original-Datei. Meine oben gemachte Vermutung, AUTOINC-Felder könnten gar nicht gelesen werden, ist also falsch. Aber der Unterschied ist nur, dass mein ID-Feld in ROW-Nodes des RAWDATA Blocks vorne steht. Daher habe ich deine Original-Datei nochmals editiert: diesmal die alten METADATA beibehalten, aber in den ROW-Zeilen, den Teil ID="..." ganz nach vorne verschoben:

Code: Alles auswählen

  <ROWDATA>
    <ROW ID="1" A="132" I="28680" U="1,27" b="750" h="408" m="104" SA="false" bf="303" tf="10" tw="8,3" Wel="1405" Wpl="1663" alpha="47,8" Grafik="" RowState="4" Hersteller="ArcelorMittal" Bezeichnung="AU 14"/>
    <ROW ID="2" A="147" I="32850" U="1,27" b="750" h="411" m="115" SA="false" bf="303" tf="11,5" tw="9,3" Wel="1600" Wpl="1891" alpha="47,8" Grafik="" RowState="4" Hersteller="ArcelorMittal" Bezeichnung="AU 16"/>
    <ROW ID="3" A="150" I="39300" U="1,33" b="750" h="441" m="118" SA="false" bf="336" tf="10,5" tw="9,1" Wel="1780" Wpl="2082" alpha="54,7" Grafik="" RowState="4" Hersteller="ArcelorMittal" Bezeichnung="AU 18"/>
  </ROWDATA>
Und wusch -- diese Datei wird problemlos gelesen.

Keine Ahnung, ob das die Lösung ist. Seltsam ist es allemal...

Ein Tipp vielleicht noch: Ich sehe in der Datei Float-Zahlen mit deutschen Dezimalkomma. Das würde ich in einer Datei auf keinen Fall machen, weil sobald ein User ein System hat, in dem der Dezimaltrenner auf Punkt eingestellt ist, fliegt dir die Datei um die Ohren. Besser: vor jedem Schreib-/Lese-Vorgang den FormatSettings.DecimalSeparator auf '.' zu setzen und hinterher wieder zurück.

[EDIT]
Kommando zurück. Auch diese "Lösungen" zeigen das eingangs geschilderte Problem, dass die Datei nicht immer fehlerlos geladen werden kann. (Leider kann ich den Beitrag nicht löschen).

Geronimo
Beiträge: 24
Registriert: Sa 1. Feb 2025, 23:22
OS, Lazarus, FPC: Winux (L 3.6.0 FPC 3.2.2)
CPU-Target: 64Bit
Wohnort: Hamburg

Re: TBufDataset: External ACCESS VIOLATION

Beitrag von Geronimo »

Moin,
nun bin ich aus dem Urlaub zurück und siehe da: Keiner hat mein Problem gelöst.
:lol:
Na dann muss ich wohl selber 'ran!

Frage an Rande: Warum kann ich nicht in die LoadFromFile Method 'reinsteppen?

Erkenntnisse durch Probieren:
Das einzige "ungewöhnliche" Feld ist <FIELD width="100000" attrname="Grafik" fieldname="Grafik" fieldtype="string"/>.
Vor allem wegen seiner Größe. Gibt es dort Beschränkungen?
Wenn ich in den Rowdata der xml-Datei dieses Feld nicht setze oder mit einem Leerzeichen setze, dann tritt der Fehler nicht mehr auf!
Mögliche Erklärung:
FieldType ftString heisst Ansistring (https://www.freepascal.org/docs-html/3. ... dtype.html).
Das Wiki sagt zum Thema Ansistring;
Assigning an empty string '' to an AnsiString variable will in fact assign nil to the variable and, if the reference count hit zero, release underlying memory (if any was previously allocated at all).
Sieht für mich nach einem String-Mischmasch in den Tiefen von Bufdataset, DB und XMLDatapacketReader aus.
Möchte jemand in diese Tiefen hinabsteigen?

Andererseits tritt der Fehler auch nicht auf, wenn ich die Größe des Feldes kleiner wähle, z.B. 1000.
(Andere kleinere Strings dürfen ja auch leer sein!)

Kann dieses Verhalten jemand von euch reproduzieren?
Wenn der Workaround ist, dass das Feld nicht leer sein darf, dann kann ich damit leben.

@ wp_xyz:
Danke für den Hinweis bezüglich des Dezimaltrennzeichens. Die Problematik ist mir bewusst. Mir war aber nicht
klar, dass ich diese Einstellungen auch global ändern kann (in der Hoffnung, dass zwischendurch im Bufdataset etc.
es niemand mehr ändert.)
Es ist eine Unsitte, alles auf Teufel komm raus mit den lokalen Sprach-/Ländereinstellungen speichern zu wollen.
Beispiel: In Excel von Fa. Winzigweich ist es unmöglich eine csv mit anderen als den Systemeinstellungen zu erstellen.
Es lebe LibreOffice!

Grüße aus Hamburg
Die Welt ist linear, rechteckig und gaussverteilt.

Antworten