AGB  ·  Datenschutz  ·  Impressum  







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

Debuggen einer Schleife

Ein Thema von MrMooed · begonnen am 16. Jan 2014 · letzter Beitrag vom 17. Jan 2014
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von MrMooed
MrMooed

Registriert seit: 18. Feb 2012
101 Beiträge
 
Delphi 7 Enterprise
 
#1

Debuggen einer Schleife

  Alt 16. Jan 2014, 22:08
Guten Abend DPler,

langsam glaube ich, dass mich Delphi trollen will.
Innerhalb einer Schleife kommt es regelmäßig zu einer AV. Jedoch ist das komische, dass sie immer an einer anderen Stelle auftritt. Mal nach der 10.000 Iteration, mal "erst" nach der 14.000

Mit einigen try-except-Blöcken konnte ich nun nachvollziehen, dass es *scheinbar* an dem Constructor eines Objekts liegt.
Delphi-Quellcode:
type
FeldArray1D = Array of TFeld;
var
folgeZustand, Zustand: TStack;
aArray: FeldArray1D
Feld: TFeld;
begin
for y:=0 to High( aArray ) do
      try
        folgeZustand.push( TZustand.create( without(aArray, y), Feld, TZustand( Zustand.top ) ) );
      except
        showmessage('Fehler bei Zustand.create'); // Wird ausgelöst
      end;
end;
Nur das (für mich) Komische ist, dass der try-except-Block in dem constructor nicht ausgelöst wird

Delphi-Quellcode:
constructor TZustand.create(const pBrennt: FeldArray1D; const pGeloescht: TFeld;
  const pVorgaenger: TZustand);
begin
  try
  lVerbrannt := pBrennt;
  fGeloescht := pGeloescht;
  zVorgaenger := pVorgaenger;
  except
    showmessage('Fehler in create'); // Keine Reaktion
  end;
end;
Kann es evtl. sein, dass nur eine begrenzte Anzahl an Objekten erstellt werden kann ? Das ganze wird wie gesagt mehrere Tausend Mal aufgerufen.
Oder gibt es einen ganz simplen Trick, mit dem ich per debugger an das Problem herangehen kann ? Denn wenn das ganze mal wieder crashed, kommt nur die AV-Meldung und das CPU-Fenster öffnet sich - nicht die gecrashte Quellcodezeile
Gruß,
MrMooed
"Unsere Luft hat einen Vorteil: Man sieht was man einatmet" - Ein Chinese
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Debuggen einer Schleife

  Alt 16. Jan 2014, 22:45
Der Fehler liegt offensichtlich nicht im Konstruktor, sondern woanders, deshalb hilft dir auch der Try-Except-Block dort nichts. Vermutlich zerschießt dir irgendwas den Speicher oder es wird auf eine Struktur zugegriffen, die schon freigegeben wurde. Mehr kann man dazu nicht sagen, ohne den kompletten Source-Code zu haben.

Wie viele Objekte man anlegen kann ist nur durch den Arbeitsspeicher begrenzt. Aber wenn der voll ist, dann kommt keine AV, sondern eine andere Exception, deren genauen Namen ich vergessen habe.

Im Zweifelsfall debugge ich solche Fehler, indem ich so lange alles auskommentiere, bis der Fehler nicht mehr auftritt.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Debuggen einer Schleife

  Alt 16. Jan 2014, 23:02
Das ist ein typisches Einsatzgebiet für FastMM. Das sagt dir im FullDebugMode evtl. sofort wo das Problem liegt.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#4

AW: Debuggen einer Schleife

  Alt 16. Jan 2014, 23:02
Wie viele Objekte man anlegen kann ist nur durch den Arbeitsspeicher begrenzt. Aber wenn der voll ist, dann kommt keine AV, sondern eine andere Exception, deren genauen Namen ich vergessen habe.
EOutOfMemory
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Debuggen einer Schleife

  Alt 17. Jan 2014, 06:23
Zitat:
Delphi-Quellcode:
try
  ...
except
  ShowMessage('nichtssagender Text');
end;
Sowas liebe ich immer.
Delphi-Quellcode:
try
  ...
except
  on E: Exception do begin
    E.Message := E.ClassName + ' in Xyz: ' + E.Message; // hier kann man z.B. auch den Index der Schleife erwähnen
    raise; // oder notfalls ShowException(E, nil); und Dergleichen
  end;
end;
Es gibt auch noch Dinge wie EurekaLog und Co., welche beim Suchen der Fehler helfen.

Wenn sich der Fehler absolut nicht finden lässt, dann kann man es auch mal so versuchen.
Delphi-Quellcode:
try
  // mach was
except
  on E: Exception do begin
    ShowException(E, nil); // <<<<<< hier ein Haltepunkt hin
    // mach es nochmal (hoffentlich tritt der Fehler nochmal auf und man kann sich dabei langsam hindurchdebuggen)
  end;
end;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#6

AW: Debuggen einer Schleife

  Alt 17. Jan 2014, 07:23
Delphi-Quellcode:
...
 for y:=0 to High(aArray) do
    folgeZustand.push
      (
       TZustand.create
         (
          without(aArray, y),
          Feld,
          TZustand(Zustand.top) /// <<---- ist 'Zustand' instantiiert?
         )
      );
  end;
Und wie ich Bandwurmcode hasse (schlecht lesbar, fehlerbehaftet, buäh), also schreib das mal übersichtlicher und formatiere deinen Code nächstes Mal zumindest ansatzweise, danke.

Delphi-Quellcode:
type
  FeldArray1D = Array of TFeld;

var
  folgeZustand, Zustand, zustandTop: TStack;
  aArray, subArray: FeldArray1D
  Feld: TFeld;

begin
  zustandTop := TZustand(Zustand.top); // Einmal vor der Schleife gemerkt, reicht.
  for y:=0 to High(aArray) do begin
    subArray := Without(aArray,y);
    neuerZustand := TZustand.create(subArray, Feld, zustandTop);
    folgeZustand.push(neuerZustand);
  end;
end;
Vielleicht ist das ja nun besser lesbar. Und wenn Zustand tatsächlich undefiniert ist (vielleicht sollte das ja eigentlich 'folgeZustand.Top' heißen, dann hättest Du auch deinen Fehler.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Debuggen einer Schleife

  Alt 17. Jan 2014, 10:46
Zitat:
Einmal vor der Schleife gemerkt, reicht
Nur wenn sich der Wert innerhalb der Schleife nicht verändert.
Aber hier weiß ja keiner was Zustand, Zustand.Top oder Without eigentlich machen.

Allerdings ist das zum Debuggen grunstäzlich erstmal genau richtig gedacht.
- So kann man eventuell mitbekommen wo, in der Schlange, es nun genu knallt.
- kann auch jeden Teil auch mit eigenen Try-Excepts testweise umgeben
- und vorallem kann man die Rückgabewerte testweise mal prüfen
- - if Assigned
- - über eine Haltepunkt-Bedingung
- - kann sich im Except den wert der zwischengespeicherten Rückgaben ansehn
- - usw.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#8

AW: Debuggen einer Schleife

  Alt 17. Jan 2014, 13:52
Zitat:
Einmal vor der Schleife gemerkt, reicht
Nur wenn sich der Wert innerhalb der Schleife nicht verändert.
Aber hier weiß ja keiner was Zustand, Zustand.Top oder Without eigentlich machen.
Ja und 'Doch, z.T.': 'Top' liefert den TOS, Zustand ist ein Stack, der lokal definiert, offenbar nicht instantiiert, nicht als Parameter verwendet und somit auch nicht verändert wird.

Falls Codeteile nicht weggelassen wurden.
  Mit Zitat antworten Zitat
Benutzerbild von MrMooed
MrMooed

Registriert seit: 18. Feb 2012
101 Beiträge
 
Delphi 7 Enterprise
 
#9

AW: Debuggen einer Schleife

  Alt 17. Jan 2014, 15:08
Erst einmal Danke für die vielen Antworten und Entschuldigung meinerseits für die etwas .. wirre Frage.

Das ist ein typisches Einsatzgebiet für FastMM. Das sagt dir im FullDebugMode evtl. sofort wo das Problem liegt.
Ein vorheriger Fehler hatte immer einen Fehler in der FastMM unit ausgelöst, weswegen ich es Test Weise deaktiviert habe - und vergessen es wieder einzubinden.
Nachdem es dann wieder eingeschaltet war, kam nicht mehr das CPU-Fenster, sondern er sprang in eine Methode - die der constructor aufruft.
[..] Falls Codeteile nicht weggelassen wurden.
Naja, Dinge wie die Initialisierung von Variablen habe ich schon weggelassen. Den ganzen Code wollte ich niemandem zumuten

Ziel des ganzen war es jedenfalls, aus einem Zustand (etwa die Stellung auf einem Schachbrett) alle möglichen folge-Zustände zu ermitteln - und die daraus folgenden.
Dem constructor
  • wird ein Array übergeben, dass alle "Spielfiguren" enthällt (außer dem, das bewegt wird)
  • das Feld, welches verändert/ bewegt wurde
  • und der vorherige Zustand
Der Fehler lag letztendlich in der Funktion 'without' - hier sollte ein Array zurückgegeben werden, das alle Elemente außer das gewählte enthällt (Das Feld das bewegt wird).
Delphi-Quellcode:
function without(var aFeldArray: FeldArray1D; aPos: Integer): FeldArray1D;
var
  i, b: Integer;
begin
  SetLength( result,
             High( aFeldArray )
            );
  b := 0;
  for i:=0 to High( aFeldArray ) do
  begin
    if not (i = aPos)
      then begin
        result[b] := aFeldArray[i]; // diese Zeile
        Inc( b ); // mit dieser vertauscht
      end;
  end;
end;
Zitat:
Delphi-Quellcode:
try
  ...
except
  ShowMessage('nichtssagender Text');
end;
Sowas liebe ich immer.
[..]
Obwohl mir die Try-Except (so wie ich sie genutzt habe) nicht viel gebracht haben, werde ich wohl demnächst darauf achten sie vernünftig zu nutzen - danke dafür
Gruß,
MrMooed
"Unsere Luft hat einen Vorteil: Man sieht was man einatmet" - Ein Chinese
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Debuggen einer Schleife

  Alt 17. Jan 2014, 16:26
Nicht obwohl, sondern weil du diese komische Exceptionbehandlung da so reingefriemelt hast, bringt dir das nichts.

Exceptions nur behandeln, wenn ich dafür eine Ausweichmöglichkeit habe.
Einfach nur einen nichtssagenden Text anzeigen ist keine.

Beispiel:

Eine simple Berechnung
Delphi-Quellcode:
function f( const x : Extended ) : Extended;
begin
  Result := 1/x;
end;
Beim Aufruf von y := f(0); wird die Exception Delphi-Referenz durchsuchenEDivByZero ausgelöst.
Na und? Wenn der erfolgreiche Ablauf von dem Wert abhängig ist, dann ist hier wohl ein Fehler passiert und der restliche Ablauf ist somit nicht mehr zu gewährleisten.

Stellen wir uns ein anderes Szenario mit der gleichen Funktion vor.
Die Funktion soll grafisch dargestellt werden. Jetzt ticken die Uhren anders
Delphi-Quellcode:
x := -1;
while x <= 1 do
begin
  try
    y := f( x );
    DrawPoint( x, y );
  except
    on E: EDivByZero do
      NoDataFor( x );
  end;
  x := x + 0.1;
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 10:18 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