AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Ab und zu unerklärliche Fehler beim Laden von XML-Daten
Thema durchsuchen
Ansicht
Themen-Optionen

Ab und zu unerklärliche Fehler beim Laden von XML-Daten

Ein Thema von Headbucket · begonnen am 18. Feb 2014 · letzter Beitrag vom 19. Feb 2014
Antwort Antwort
Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Ab und zu unerklärliche Fehler beim Laden von XML-Daten

  Alt 18. Feb 2014, 08:02
Delphi-Version: XE5
Hallo,

ich habe zur Zeit ein recht nerviges Problem, welches ich euch hier mal kurz schildern möchte.
Ich habe ein Programm, welches im OnShow-Event des Hauptformulars alle Werte verschiedener XML-Dateien laden soll. Das funktioniert manchmal wunderbar, manchmal kommen aber auch an ständig anderen Stellen verschiedene Fehler.

Beispiele für Fehler:
  • 'M' ist kein gültiger Gleitkommawert - obwohl unter dem angefordertem Knoten eine 0 steht. Die Knoten, bei denen dieser Fehler auftritt sind absolut zufällig genauso wie der Buchstabe
  • Access violation: read of adress 0xfffffffc - hier bleibt er in der GETMEM.INC bei Zeile 1904 hängen (jedesmal an der selben Stelle).:
    Delphi-Quellcode:
    {Get the new first free block}
    and ecx, [eax - 4]
  • Access violation: read of address 0x00000002 - hier bleibt er in der System-Unit in folgender Funktion hängen:
    Delphi-Quellcode:
    class function TMonitor.GetFieldAddress(const AObject: TObject): PPMonitor;
    begin
      Result := PPMonitor(PByte(AObject) + AObject.InstanceSize - hfFieldSize + hfMonitorOffset);
    end;

Das sind zumindest mal die drei häufigsten Fehler. Wahrscheinlich kann man jetzt noch gar nicht helfen. Leider ist es mir nicht möglich/gestattet hier den kompletten Code zu posten. Dennoch hier der grobe Ablauf

Delphi-Quellcode:
procedure LoadObjects;
var
  threadID: DWord;
begin
  CreateThread(nil, 0, TFNThreadStartRoutine(@LoadObjectsThreadFunc), nil, 0, threadId);
end;
Delphi-Quellcode:
procedure LoadObjectsThreadFunc(p: pointer);
var
  si: TObjectUseType;
  sl: TStringList;
  err: string;
begin
  CoInitialize(nil);

  WaitForSingleObject(g_LoadObjectsMutex, INFINITE); //CreateMutex wurde vorher aufgerufen

  sl := TStringList.Create;

  for si := Low(TObjectUseType) to High(TObjectUseType) do
  begin
    g_dataManager.getFiles(sl, ObjectFileType[si]);
    g_Objects[si].loadFromXMLFiles(sl,err); //DANACH FEHLER
    g_Objects[si].Sort(g_SortType);
  end;

  FreeAndNil(sl);

  ReleaseMutex(g_LoadObjectsMutex);
end;
Delphi-Quellcode:
function TPersistentObjectList.LoadFromXMLFiles(const sl: TStringList; var err: string): boolean;
var
  FXMLDoc: TXMLDocument;
  FSaver: TXMLSaverBase;
  i: integer;
  FValue: TPersistent_;
  FNode: IXMLNode;
begin
  err := '';
  Result := true;
  Clear;
  try
    try
      FSaver := TXMLSaverBase.Create;
      if assigned(sl) then
      begin
        for i := 0 to sl.Count-1 do
        begin
          FXMLDoc := TXMLDocument.Create(Application);
          FXMLDoc.FileName := sl.Strings[i];
          FXMLDoc.Active := true;
          FNode := FXMLDoc.DocumentElement;
          FSaver.Node := FNode;
          FValue := TPersistent_Class(GetClass(FSaver.GetStrAttribute(CXML_CLASSNAME,'',true))).Create;
          Result := FValue.loadFromXMLNode(FNode,err); //Fehler
          FValue.FileName := sl.Strings[i];
          Add(FValue);
          FreeAndNil(FXMLDoc);
        end;
      end
      else
        Result := false;
    finally
      FreeAndNil(FSaver);
    end;
  except
    Result := false;
  end;
end;
Delphi-Quellcode:
function TObjectXYZ.loadFromXMLNode(iNode: IXMLNode;
  var err: string): boolean;
var
  FSaver: TXMLSaverBase;
  FNode: IXMLNode;
begin
  Result := true;
  inherited loadFromXMLNode(iNode,err);
  try
    try
      FSaver := TXMLSaverBase.Create;
      FSaver.Node := iNode;
      FIrgendwas := FSaver.GetDoubleAttribute(CXML_Irgendwas,0,true); //manchmal bleibt er hier stehen
      FWasAnderes := FSaver.GetBoolAttribute(CXML_WasAnderes,false,true); //manchmal auch hier
      {...}
    finally
      FreeAndNil(FSaver);
    end;
  except
    on E: Exception do
    begin
      err := E.Message;
      Result := false;
    end;
  end;
end;
Delphi-Quellcode:
function TXMLSaverBase.GetDoubleAttribute(const AttributeName: string; DefaultValue: Double; SendException: boolean): Double;
begin
  Result := StrToFloat_(GetAttribute(AttributeName, FloatToStr_(DefaultValue), SendException));
end;
Delphi-Quellcode:
function TXMLSaverBase.GetAttribute(const AttributeName: string; DefaultValue: OleVariant; SendException: boolean): OleVariant;
  function DoDefault(SendException: boolean): OleVariant;
  begin
    if SendException then
      raise EXMLReadException.Create(' GetAttribute: Node: ' + FNode.NodeName)
    else
      Result := DefaultValue;
  end;
begin
  FLastReadError := emptystr;
  Result := 0;
  try
    if Assigned(FNode) then
    begin
      if(HasAttribute(AttributeName)) then
        Result := FNode.Attributes[AttributeName]
      else
        Result := DoDefault(SendException);
    end
    else
    begin
      Result := DoDefault(SendException);
    end;
  except
    Result := DoDefault(SendException);
  end;
end;
Der Call-Stack sieht auch jedes mal etwas anders aus. Es hängt auch irgendwie damit zusammen, wann ich die XML-Dateien lade. Wenn ich sie z.B. beim Klick auf einen Button lade treten noch ganz andere Fehler auf. Zum Beispiel "zu wenig Arbeitsspeicher" (sind 8GB vorhanden und nie ansatzweise voll).

Ich kann mir vorstellen, dass man da wohl nur schwer von außen helfen kann aber vllt hat ja doch jemand eine Idee. Vllt auch ein paar Tipps, wie ich vorgehen kann, um den Fehler einzugrenzen. Hintergrund: Ich muss ein großes Delphi-Projekt von Delphi 7 auf XE5 umstellen und verwende dabei einige Units (wie z.B. XMLSaverBase) des alten Projektes um einigermaßen kompatibel zu bleiben. Die Fehler treten ja wie gesagt auch nur bei jedem 7ten Start oder so auf.

Vielen Dank für eure Mühe.

Grüße
Headbucket
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Ab und zu unerklärliche Fehler beim Laden von XML-Daten

  Alt 18. Feb 2014, 08:16
Ohne wirklich eine konkrete Idee zu haben würde ich als erstes schauen, ob der Aufruf von CoInitialize(..) auch wirklich immer klappt. Ob da weiterhin im Zusammenhang mit COM reinspielt, dass du deinen Thread direkt über die WinAPI aufmachst weiß ich nicht, könnte doch vielleicht auch sein?

// Übrigens:
Warum erstellst du ein TXMLDocument, explizit mit Application als Eigentümer-Komponente, gibst es aber selbst ein paar Zeilen später doch gewaltsam frei? Da würde ich auf IXMLDocument als Referenz-Typ umsteigen. Einladen dann mit Xml.XMLDoc.LoadXMLDocument(const Filename: String) .

Geändert von Der schöne Günther (18. Feb 2014 um 09:57 Uhr)
  Mit Zitat antworten Zitat
Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Ab und zu unerklärliche Fehler beim Laden von XML-Daten

  Alt 19. Feb 2014, 14:57
Vielen dank für deine Antwort.
Ohne wirklich eine konkrete Idee zu haben würde ich als erstes schauen, ob der Aufruf von CoInitialize(..) auch wirklich immer klappt.
Das sollte eigentlich immer klappen, da mir sonst eine Exception mit der Meldung "Microsoft MSXML ist nicht installiert" entgegen springt.
Ob da weiterhin im Zusammenhang mit COM reinspielt, dass du deinen Thread direkt über die WinAPI aufmachst weiß ich nicht, könnte doch vielleicht auch sein?
Du meinst, weil ich dem erzeugten Thread keinen Handle zuweise? Das habe ich eben mal probiert - brachte jedoch keine Besserung.
// Übrigens:
Warum erstellst du ein TXMLDocument, explizit mit Application als Eigentümer-Komponente, gibst es aber selbst ein paar Zeilen später doch gewaltsam frei? Da würde ich auf IXMLDocument als Referenz-Typ umsteigen.
Ich schätze fast, dass hier das Hauptproblem liegt. Ich verwende, wie schon erwähnt, alte Quellen eines anderen Softwareentwicklers, um die Kompatibilität zu gewähren. Diese sind auch relativ umfangreich und ich würde wohl eine ganze Weile brauchen diese neu zu schreiben. Es ging ja bisher (mit Delphi 7 und XE2) auch immer.
Ich habe aber auch schonmal versucht an der ein oder anderen Stelle ein Interface zu benutzen - bisher aber auch ohne Erfolg.

Habe soeben auch nochmal mein XE5 auf den neusten Stand gebracht - hat aber auch nicht geholfen.

Schwierig :-/

Eine Idee, wie ich mich da Schritt für Schritt rantasten könnte? Es ist halt schwierig, da die Fehler unterschiedlich sind und an unterschiedlichen Stellen auftauchen.

/////Edit/////
Ich habe soeben mal das ganze Mutex/Thread-Gedöns weggelassen und siehe da: Es funktioniert. Zumindest konnte ich dem Programm nach 50 mal starten keinen Fehler entlocken.
Von der Theorie her sollte das ganze jedoch schon in einen Thread gepackt werden, da sehr viele Datensätze gelesen werden sollen und somit verhindert werden soll, dass jemand anders während des Ladens auf die Daten zugreift.

Aber das Problem lässt sich sicher lösen und ist mir deutlich lieber als ein Problem mit der XML-Verarbeitung.

Wie ich bisher vorgegangen bin:
(1) CreateMutex im Initialization-Abschnitt
(2) CreateThread und damit Aufruf der Procedure zum Laden
(3) CoInitialize -> WaitForSingleObject -> Laden -> ReleaseMutex
(4) CloseHandle im Finalization-Abschnitt

Das ganze habe ich auch schon etwas abgewandelt - jedoch ohne Erfolg.
Ich werd nochmal etwas Suchen und rumprobieren.

Geändert von Headbucket (19. Feb 2014 um 15:27 Uhr) Grund: Update
  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 20:20 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