Debugging

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

Debugging

Beitragvon charlytango » 22. Jul 2017, 19:48 Debugging

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
charlytango
 
Beiträge: 104
Registriert: 12. Sep 2015, 11:10
Wohnort: Wien
OS, Lazarus, FPC: FPC 3.0; Laz 1.6 | 
CPU-Target: Win 32Bit, 64bit
Nach oben

Beitragvon Michl » 22. Jul 2017, 19:55 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; 
Michl
 
Beiträge: 2169
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon charlytango » 23. Jul 2017, 10:46 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.
charlytango
 
Beiträge: 104
Registriert: 12. Sep 2015, 11:10
Wohnort: Wien
OS, Lazarus, FPC: FPC 3.0; Laz 1.6 | 
CPU-Target: Win 32Bit, 64bit
Nach oben

Beitragvon af0815 » 23. Jul 2017, 11:00 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
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
af0815
 
Beiträge: 3258
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: Win7/Linux (L stable FPC stable) per fpcup | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon wp_xyz » 23. Jul 2017, 11:08 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).

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.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
wp_xyz
 
Beiträge: 2250
Registriert: 8. Apr 2011, 08:01

Beitragvon Michl » 23. Jul 2017, 14:39 Re: Debugging

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.
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.

@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; 
Michl
 
Beiträge: 2169
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

• Themenende •

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron
porpoises-institution
accuracy-worried