HeapOverflow/RunError(203) bei dynam. StringList [gelöst]

Für Fragen von Einsteigern und Programmieranfängern...
and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

HeapOverflow/RunError(203) bei dynam. StringList [gelöst]

Beitrag von and4more »

Hallo liebes Forum, habe schon im Internet recherchiert komme aber nicht weiter. Folgendes Problem: Ein Programm, was unter den bisherigen Lazarus-Versionen bis inkl. 1.4.x klaglos funktioniert schmeißt mir nach Update auf Lazarus 1.6 plötzlich einen RunError(203) vor die Füße, allerdings nur bei 32 Bit Kompilat unter Windows 10, nicht bei 64 Bit Windows 10 oder Linux. Mit heaprc lässt sich erkennen, dass der Fehler beim Erzeugen einer dynamischen StringList auftritt, die mittels Stringlist.Add erzeugt wird. Könnte es sein, dass dies ein Bug ist (internes Pointerproblem?)? Weiß jemand eine Möglichkeit zum Umgehen?
Danke für's Kopf zerbrechen und Liebe Grüße
Zuletzt geändert von and4more am So 10. Jul 2016, 16:50, insgesamt 1-mal geändert.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2640
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von m.fuchs »

Ein wenig Quellcode wäre schön.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von and4more »

...ok, ich versuch's mal soweit zusammenzufassen, da es ziemlich umfangreich ist:

Code: Alles auswählen

 
procedure TErgebnisse.makeContent(Sender:TObject);
...
  if Assigned(InhaltListe) then InhaltListe.Clear //wenn Inhaltliste existiert, leeren
  else InhaltListe:=TStringList.Create;
  try
    // ***** Zusammenfassung der Ergebnisse *****
    // ----- HTML-Header mit Platz für Firmenlogo oben ----
    InhaltListe.Add(HtmlHeader); // Header
    InhaltListe.Add(HtmlB);      // Titel
    InhaltListe.Add(HtmlBC);     // Body-Content Format
    // --------- Inhalt ---------------------------
    with FrmMain do begin
      InhaltListe.Add(HtmlLL+'<b>..... </b></th>'+'<th align="left" colspan="1">'+'<b>'+EdUTT.Text+'.'+....
      InhaltListe.Add(HtmlLL+'... '+HtmlRL+EdVorname.Text+' '+EdName.Text+'</td></tr>');
      InhaltListe.Add(....)
      InhaltListe.Add(....)
      ..... //sehr lange Liste wobei Daten teils in Variablen in einer anderen Unit gespeichert sind, teils über das Programm erstellt werden
      .... 
  finally
  ....
end;
 


Die Procedure selbst ist in einer eigenen Unit. In einer "Variablen"-Unit sind Texte mit HTML-Code abgelegt und frei abgelegt, da eine HTML-Seite über IpHtml erzeugt wird, Möglicherweise ist aber auch die Übergabe an IpHtml,also die Generierung als HTML-Seite das Problem, da im Programm die StringList im Fentster erscheint, die HTML-Version ab leer ist Ich weiß jetzt nicht, ob diese Infos hilfreich sind
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von and4more »

Nachtrag: Das Ganze wird dann an ein Memofeld- und HTML-Fenster übergeben:

Code: Alles auswählen

 
procedure TErgebnisse.FormShow(Sender: TObject);
begin
  MResult.Clear;
  try
    makeContent(Sender);
    MResult.Text:=InhaltListe.Text;
    HtmlResults.SetHtmlFromStr(InhaltListe.Text);  // Ergebnis in HTML
  finally
  end;
end;
 
// Button zur Übernahme von im Memofeld geändertem Text
procedure TErgebnisse.BitBWriteClick(Sender: TObject);
begin
  //HtmlResults.;
  //----- Transfer von Memofeld in HTML -----
    HtmlResults.SetHtmlFromStr(MResult.Lines.Text);
  HtmlResults.SetFocus;
end;
 
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2640
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von m.fuchs »

Naja, das sagt noch nicht soviel aus. ABER: wenn du bei solchen Erzeugungsoperationen unter 32-Bit einen RunError 302 kassierst unter 64 Bit jedoch nicht, ist dein Speicher wohl ausgereizt. Ich vermute jetzt mal, dass du irgendwo etwas nicht richtig aufräumst.

Wie groß ist denn der Speicherbedarf des laufenden Programms unter Win64?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von theo »

Ich sehe es so nicht.
Der Weg zu einem allfälligen Bug-Report führt darüber, das Problem zu isolieren.
Also mache ein kleines, vollständiges Programm, welches den Fehler aufweist.
In den allermeisten Fällen findet man auf dem Weg dahin auch den womöglich eigenen Fehler. :wink:

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von and4more »

@ m.fuchs: Der Speicher (gleiches Gerät) ändert sich ja nicht je nachdem, ob ich das Programm mit 32- oder 64-Bit kompiliere. Was sich allerdings ändert ist die Menge des internen Speichers, die ich adressieren kann mit 32-/64-Bit. Das allein würde dann aber immer noch nicht erklären warum es mit Lazarus 1.4.x und kleiner geklappt hat und mit 1.6 nicht, wie gesagt: Gleiches Gerät (8 GB RAM)
@theo: Tja, also wenn ich wüsste welche Funktion den Error wirft hätte ich wahrscheinlich nicht gepostet, sondern es gleich gefixt. Insofern wird es mir naturgemäß schwer fallen ein kleines Programm zu schreiben, welches den Fehler repliziert. M. E. könnte der Fehler in der Übergabe der StringList an die HTML-Funktion liegen. Der Dump von heaptrc zeigt jedesmal andere Werte, allerdings kann ich mit diesen zahlen (Speicherbereiche?) auch nicht so wahnsinnig viel anfangen.

Gibt es denn eine "sichere" Funktion zum Übertragen von Text aus dem Memofeld/StringList in HTML?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von Michl »

Ich glaube nicht an einen Fehler einer TStringList. Diese wird sehr oft eingesetzt. So einen Fehler wäre vermutlich eher aufgefallen.

Ich pflichte theo bei. Um so einen Fehler zu finden, dem man mit dem Debugger nicht auf die Spur kommt, empfiehlt sich eine Reduktion. Einfach eine Kopie vom aktuellen Projekt erstellen und immer das rausschmeißen, was man als Fehlerquelle auschließt. Übrig bleibt zumeist ein kleines Beispiel, wo man selber den Fehler sieht oder man es hier posten kann.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von theo »

and4more hat geschrieben:@theo: Tja, also wenn ich wüsste welche Funktion den Error wirft hätte ich wahrscheinlich nicht gepostet, sondern es gleich gefixt. Insofern wird es mir naturgemäß schwer fallen ein kleines Programm zu schreiben, welches den Fehler repliziert.


Kann schon sein, aber die Alternative zur Reduktion des Fehlers auf ein Minimum an Kontext ist das Kaffeesatzlesen. :wink:

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von and4more »

@michl: Hmmm, tja wenn das so einfach wäre, bin doch hier bei den Einsteigerfragen, oder? Scherz beiseite, es handelt sich im Prinzip um ein ganz simples Programm, welches im Grunde nur aus einem Hauptfenster mit Notebook-Tabs und Eingabefeldern besteht. Diese werden in einer StringList abgelegt und das Ganze in ein Memofeld und ein HTML-Feld übertragen, voila. Ich wüsste jetzt ehrlich nicht wo ich da noch was vereinfachen sollte. Im Gegenteil gehe ich sogar davon aus, dass es wahrscheinlich bei Verringerung der Datenmenge in der StringList funktionieren dürfte, da es dann beim Transfer in das HTML-Feld (möglicherweise) zu keinem Speicherüberlauf mehr kommt. Werde ich aber Spaßes halber mal machen, wenn ich wieder etwas mehr Zeit habe. Allerdings ist mir noch nicht klar wie mir das bei meinem Problem helfen würde, wenn der Laufzeitfehler plötzlich weg wäre, denn was will ich mit einem halben Programm?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

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

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von wp_xyz »

Oh Mann! Das wird doch nicht dein endgültiges Programm. Die Arbeit ist ja nur zur Fehlersuche. Und an einen Speicherüberlauf zu Zeiten von > 8GB in der Kiste glaube ich übrigens schon gar nicht. Wieviele GB willst du denn in Stringlist/Memo/HTMLPanel eintragen? Eine Grenze gibt es allerdings vorher bei TStringList: MaxListSize = MaxInt div 16. Aber wenn du da in die Nähe kommst, solltest du dich fragen, ob du deinen Usern wirklich ein Memo mit 134 Millionen Zeilen zumuten willst.

Du beschreibst doch recht schön die Ausgangssituation: du hast eine Stringlist, die in ein Memo und in ein HTMLPanel geladen wird. Also würde ich in dem Testprogramm erstmal einen gültigen HTML-Text in die Stringlist, Memo und HTMLPanel laden. Falls das nicht klappt, hast du beim ersten Schritt den Problem schon extrem vereinfacht, denn dieser muss auf jeden Fall funktionieren. Falls andererseits kein Fehler auftritt, packst du stückweise immer mehr von deinem eigentlichen Programm dazu, bis irgendwann der Fehler kommt. Als Nebeneffekt wirst du dabei sehen, dass wahrscheinlich die Datenübergabe viel zu kompliziert und verkorkst ist.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2640
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von m.fuchs »

wp_xyz hat geschrieben:Und an einen Speicherüberlauf zu Zeiten von > 8GB in der Kiste glaube ich übrigens schon gar nicht.

Da der Fehler nur bei 32-Bit auftritt sind die 8 GiB RAm völlig egal. Das Programm könnte sowieso nur maximal 2 GiB adressieren unter Windows. Dass es bei Lazarus 1.4 klappt und bei Lazarus 1.6 nicht könnte dann damit erklärbar sein, dass sich Code und Speicherbedarf in RTL/FCL/LCL geändert hat. Ist ja auch nur eine (vielleicht auch weit hergeholte)Vermutung, aber die wäre leicht nachzuprüfen, wenn der OP einfach mal prüfen würde wieviel RAM sein Programm als 64-Bit-Version belegt. Und vielleicht auch gleich wieviel RAM das Programm als 32-Bit belegt während es crasht.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

BeniBela
Beiträge: 309
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von BeniBela »

Da sollte man erstmal die ganzen Debugflags setzen: -gh -CrRiot -Sa

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von Michl »

BeniBela hat geschrieben:Da sollte man erstmal die ganzen Debugflags setzen: -gh -CrRiot -Sa
Das sollte man bei einer Fehlersuche tatsächlich, nur nützt das hier wahrscheinlich nichts. Wenn man nicht ordentlich aufräumt tritt der Fehler an einer zufälligen Stelle auf.
Bsp.:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  SL1, SL2: TStringList;
begin
  while True do begin
    TStringList.Create;
    SL1 := TStringList.Create;
    SL2 := TStringList.Create;
    SL2.Free;
    SL1.Free;
  end;
end
Wirft bei mir regelmäßig bei SL2 := TStringList.Create; den RunError(203), obwohl die Ursache zwei Zeilen höher liegt.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: HeapOverflow/RunError(203) bei dynamischer StringList

Beitrag von and4more »

Zunächst vielen Dank für die vielen guten Ratschläge. Wenn die Funktion auskommentiert wird, die die StringList in das HTML-Panel überträgt läuft das Programm klaglos. Auch lässt sich der gleiche Speicherüberlauf bei Drücken des Buttons erzeugen, der das Memofeld in das HTML-Panel überträgt.

Code: Alles auswählen

 
procedure TErgebnisse.FormShow(Sender: TObject);
begin
  MResult.Clear;
  try
    makeContent(Sender);
    MResult.Text:=InhaltListe.Text;
//    HtmlResults.SetHtmlFromStr(InhaltListe.Text);  // Ergebnis in HTML
  finally
  end;
end;
 
procedure TErgebnisse.BitBWriteClick(Sender: TObject);
begin
  //HtmlResults.;
  //----- Transfer von Memofeld in HTML -----
    HtmlResults.SetHtmlFromStr(MResult.Lines.Text);   // hier tritt der Speicherüberlauf ebenfalls auf
  HtmlResults.SetFocus;
end;
 


Es scheint also kein Problem mit der StringList, als vielmehr ein Problem bei deren Übertragung in das HTML-Panel zu sein. Jetzt natürlich die Frage: Gibt es einen anderen Weg die Stringlist/das Memofeld in das HTML-Panel zu transferieren, der Absturzsicherer ist?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Antworten