Hi,
in einer Applikation mit etlichen Formularen samt DB-Anbindung verhalten sich die Formulare "normalerweise" wie gewünscht.
Unter bestimmten Umständen gibt es beim Schließen der Applikation und damit dem Schließen offener Formulare eine Exception in TZAbstractRODataset.GetRecordCount weil offensichtlich zu diesem Zeitpunkt (Operation cannot be performed on an inactive dataset) ein Datenset nicht aktiv ist.
So weit so nachvollziehbar. Bloß finde ich dieses sch..öne Datenset nicht.
Jetzt hab ich schon etliche Zeit investiert auf der Jagd nach diesem offenen Datenset. Durchsteppen, Breakpoints etc. hab ich schon durch -- vermutlich aber nicht am richtigen Ort oder zur richtigen Zeit. Scheinbar sind meine Debuggingfähigkeiten noch immer mangelhaft.
Nach der Exception steht der Code bei TZAbstractRODataset.GetRecordCount -- eigentlich müsste ich "nur" wissen welches Codestück diese Funktion aufgerufen hat, leider bin ich da mit meinem Latein am Ende.
Auch über CheckActive in der Funktion GetRecordCount bekomme ich nix über das betroffene Datenset heraus.
Gibt es eine Methode etwa den Callstack zu befragen oder herauszubekommen wie das betroffene Datenset heißt ?
Bin für sachdienliche Hinweise zur Ergreifung des Bugs dankbar
Danke im Voraus
Debugging
-
- Beiträge: 844
- 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: Debugging
Der GDB arbeitet bei mir (Windows 7, Lazarus 32bit) am besten mit Dwarf2 Debugsymbolen (-gw2). In der IDE kannst du dir mit <Strg> + <Alt> + <S> den Aufrufstack anzeigen lassen. Weitere Infos: http://wiki.lazarus.freepascal.org/GDB_Debugger_Tips
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 844
- 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: Debugging
Michl hat geschrieben:Der GDB arbeitet bei mir (Windows 7, Lazarus 32bit) am besten mit Dwarf2 Debugsymbolen (-gw2). In der IDE kannst du dir mit <Strg> + <Alt> + <S> den Aufrufstack anzeigen lassen. Weitere Infos: http://wiki.lazarus.freepascal.org/GDB_Debugger_Tips
Danke erstmal, aber irgendwie komm ich auch damit nicht weiter.
mittlerweile vermute ich dass der auf dem Form befindliche DB-Grid für den RecordCount-Aufruf zuständig ist, um die Größe der Scroll-Leisten zu berechnen.
- af0815
- Lazarusforum e. V.
- Beiträge: 6213
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Debugging
Was siehst du im Aufrufstack (wie oben beschrieben) wenn der Fehler auftritt ? Hinweis, ev. muss man auf Max. 50 umschalten, damit man sieht wo das herkommt. Kannst ja auch den Inhalt mit 'alle kopieren' mal hier hereinstellen.
Andreas
Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: Debugging
Dann hier eine Schnellanleitung, wie man mit dem CallStack arbeitet:
Hier ist ein Programm (einfaches Formulat mit einem Button), das eine Exception beim Klick auf den Button erzeugt (weil in der Anweisung "Format()" ein Platzhalter für einen Integer verwendet wird, als Parameter aber ein String übergeben ist).
Wenn du dieses Programm laufen lässt und nach dem Click auf den Button die Exception erzeugt wird, klickst du in der Meldungsbox der Exception auf "Anhalten" und öffnest das Fenster des Aufruf-Stacks - Tastenkombinationen sind wegen der Konfigurierbarkeit etwas problematisch, aber sicher geht's mit "Ansicht" > "Debugger-Fenster" > "Aufrufstack". Der sieht bei diesem Programm zu diesem Zeitpunkt so aus wie in dem Screenshot. Ganz oben steht die Routine, die die Exception ausgelöst hat - das ist irgend eine Routine im FPC-Code. Nach unten siehst du diejenigen Routinen, die jeweils die darüberstehende aufgerufen haben. Wenn du also von oben nach unten gehst, stößt du in der Zeile mit der Nr 5 auf die Funktion "TFORM1_BUILDMSG...", Zeile 36. Das ist die letzte Zeile aus dem eigenen Code, als es zum Fehler gekommen ist. Gehe zu dieser Zeile, und du bist an der Fehlerursache. Manchmal wird allerdings der Fehler weiter außen angelegt. In diesem fall musst du natürlich auch die darunterstehenden Zeilen prüfen.
Hier ist ein Programm (einfaches Formulat mit einem Button), das eine Exception beim Klick auf den Button erzeugt (weil in der Anweisung "Format()" ein Platzhalter für einen Integer verwendet wird, als Parameter aber ein String übergeben ist).
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
function BuildMsg: String;
procedure DisplayMessage;
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
function TForm1.BuildMsg: String;
begin
Result := Format('String mit falschem Platzhalter %d', ['Hallo']);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DisplayMessage;
end;
procedure TForm1.DisplayMessage;
var
s: String;
begin
s := BuildMsg;
ShowMessage(s);
end;
end.
Wenn du dieses Programm laufen lässt und nach dem Click auf den Button die Exception erzeugt wird, klickst du in der Meldungsbox der Exception auf "Anhalten" und öffnest das Fenster des Aufruf-Stacks - Tastenkombinationen sind wegen der Konfigurierbarkeit etwas problematisch, aber sicher geht's mit "Ansicht" > "Debugger-Fenster" > "Aufrufstack". Der sieht bei diesem Programm zu diesem Zeitpunkt so aus wie in dem Screenshot. Ganz oben steht die Routine, die die Exception ausgelöst hat - das ist irgend eine Routine im FPC-Code. Nach unten siehst du diejenigen Routinen, die jeweils die darüberstehende aufgerufen haben. Wenn du also von oben nach unten gehst, stößt du in der Zeile mit der Nr 5 auf die Funktion "TFORM1_BUILDMSG...", Zeile 36. Das ist die letzte Zeile aus dem eigenen Code, als es zum Fehler gekommen ist. Gehe zu dieser Zeile, und du bist an der Fehlerursache. Manchmal wird allerdings der Fehler weiter außen angelegt. In diesem fall musst du natürlich auch die darunterstehenden Zeilen prüfen.
Re: Debugging
Falls der Debugger bzw. die Debugsymbole nicht richtig eingestellt sind, kann es auch passieren, daß Haltepunkte nicht angesprungen werden - das darf nicht sein. Daher der Hinweis mit Dwarf2, siehe oben. Soweit ich mich richtig erinnere, ist das unter Linux GTK2 auch so.wp_xyz hat geschrieben:Manchmal wird allerdings der Fehler weiter außen angelegt. In diesem fall musst du natürlich auch die darunterstehenden Zeilen prüfen.
@OP: Das CallStack-Window ist bei mir immer geöffnet. Dank AnchorDocking ist das Ganze auch sehr übersichtlich. Ohne die richtigen Debug-Projekteinstellungen und ohne Auswertung des CallStacks wäre ich echt aufgeschmissen. Daher teste mal ein wenig das Debuggen, schaue dir mal mal an, wie man sich überwachte Ausdrücke und deren Properties beim Debuggen anzeigt, manchmal sind auch Ausgaben auf der Console sinnvoll, usw. Ohne diese Tools ist eine effektive Fehlersuche nicht denkbar.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;