![]() |
Datenbank: MySQL • Version: 51 • Zugriff über: TSQL51Connection
SIGSEGV bei öffnen einer SQL-Query
Ich brauche mal wieder einen Denkanstoß bzw. Hilfe zur Fehlersuche. Mein Projekt sieht grob zusammengefasst so aus:
Hauptfenster:
Hierzu wird im Hauptfenster bei Doppelklick jeweils das Editierfenster per Create erzeugt ünd modal angezeigt. Nach mehrfachem Öffnen (und jeweils wieder schließen via mrCancel) kommt es plötzlich beim erneuten Öffnen zu einem SIGSEGV. Ich versuche seit Tagen den Fehler einzugrenzen, was mir nicht gelingen will. Immer wenn ich denke das Problem gefunden zu haben und meinen Code abändere, kommt der Fehler an anderer Stelle. Wie kann ich herausfinden, woher der Fehler kommt? Hier mal der Teil des Hauptfensters, der das Editfenster zeugt:
Delphi-Quellcode:
Und hier der Destructor des Detailfensters:
procedure TMain.Men_TerminEditClick(Sender: TObject);
var s: integer; begin if Assigned(MyDatabase) then begin if MyUser.IsAllow(read) then begin S:= SQLQuery2.FieldByName('ID').AsInteger; SQLQuery2.Close; frm_MyTermin:=Tfrm_MyTermin.Create(self, MyDatabase, MyUser); frm_MyTermin.execute(s); freeandnil(frm_MyTermin); SQLQuery2.Open; SQLQuery2.Locate('ID',s,[]); end; end else Showmessage('Es besteht keine Datenbankverbindung'); end;
Delphi-Quellcode:
Ich vermute, daßß irgendwo der Speicher nicht komplett freigegeben wird.
destructor Tfrm_myTermin.destroy;
begin DBLookupName.ListSource:= nil; DBLookupVName.ListSource:= nil; DBLookupOP.ListSource:= nil; DBLookupEinw.ListSource:= nil; SQLQuery1.Active:= false; SQLQuery2.Active:= false; SQLQuery3.Active:= false; sqlQuery4.Active:= false; SQLQuery5.Active:= false; SQLQuery6.Active:= false; SQLTransaction1.CloseTrans; SQLTransaction1.Free; SQLTransaction2.CloseTrans; SQLTransaction2.Free; SQLTransaction3.CloseTrans; SQLTransaction3.Free; SQLTransaction4.CloseTrans; SQLTransaction4.Free; SQLTransaction5.CloseTrans; SQLTransaction5.Free; SQLTransaction6.CloseTrans; SQLTransaction6.Free; inherited destroy; end; Vielen Dank für Eure Hilfe. |
AW: SIGSEGV bei öffnen einer SQL-Query
Ich würde die Form-Variable lokal deklarieren und einen Ressourcenschutzblock einbauen.
Delphi-Quellcode:
Konstruktor und Destruktor von Tfrm_MyTermin hast Du hoffentlich überschrieben? Wobei ich mich frage, wieso Du den Destruktor verwendest und nicht das OnDestroy-Event des Formulars. Wenn die Komponenten schon zur Designtime darauf platziert wurden (oder beim Erzeugen das Formular als Owner angegeben wurde), ist die Freigabe auch überflüssig, da dies sowieso automatisch geschieht.
procedure TMain.Men_TerminEditClick(Sender: TObject);
var s: integer; frm_MyTermin: Tfrm_MyTermin; begin if Assigned(MyDatabase) then begin if MyUser.IsAllow(read) then begin S:= SQLQuery2.FieldByName('ID').AsInteger; SQLQuery2.Close; frm_MyTermin:=Tfrm_MyTermin.Create(self, MyDatabase, MyUser); try frm_MyTermin.execute(s); finally frm_MyTermin.Free; end; SQLQuery2.Open; SQLQuery2.Locate('ID',s,[]); end; end else Showmessage('Es besteht keine Datenbankverbindung'); end; |
AW: SIGSEGV bei öffnen einer SQL-Query
Danke für die schnelle Antwort. Ich habe nun die Formularvariable lokal deklariert, wie von Dir vorgeschlagen. Der Fehler beim Create und wird nicht vom Programm erzeugt, sondern es kommt ein kommentarloses SIGSEGV vom Betriebssystem. Daher funktioniert das abfangen mit try auch nicht. Create und destroy sind im Formular wie folgt deklariert:
Delphi-Quellcode:
Destroy deshalb, weil die Transactions eine abgeleitete Klasse von TSQLTransaction sind und zur Laufzeit erzeugt (create des Formulars) werden. Das war nötig, weil bei Lazarus die originale Transaction buggy ist und ein Speicherleck hinterlässt, wenn nicht CloseTrans explizit aufgerufen wird. Bin noch immer ratlos. Wie kann ich herausbekommen, ob Speicher irgendwo nicht wieder freigegeben wird?
public
{ public declarations } constructor Create (AOwner : TComponent ; AConnection : TMyConnection; AUser: TMyUser) ; reintroduce ; destructor destroy; override; |
AW: SIGSEGV bei öffnen einer SQL-Query
Habe jetzt etwas umgebaut. Das Fenster wird nun bereits in der Programmdatei (myprog.lpr) erzeugt.
Delphi-Quellcode:
In meinem Hauptfenster wird nun eine frm_MyTermin.Init aufgerufen, die MyDatabase (TMysql51Connection) und mein Userobject MyUser an das Fenster übergiebt und meine Querys und Transactions entsprechend setzt. Anschließend zum (modalen) Anzeigen des Fensters wieder frm_MyTermin.execute.
Application.CreateForm(Tfrm_MyTermin, frm_myTermin);
Das SIGSEGV kommt noch immer, aber erst nach viel mehr Aufrufen des Fensters.:cry: Ich bin zu blöd den Fehler zu finden! |
AW: SIGSEGV bei öffnen einer SQL-Query
Zur Sicherheit solltest du als Owner des modalen Formulars nil angeben:
Delphi-Quellcode:
Übergibt man einen Owner, dann hat das im Hintergrund viele Aufrufe von
frm_MyTermin:=Tfrm_MyTermin.Create(nil {<=nicht self}, MyDatabase, MyUser);
try frm_MyTermin.execute(s); finally frm_MyTermin.Free; end;
Delphi-Quellcode:
zur Folge, was manchmal zu sehr seltsamen Effekten führen kann.
TComponent.Notification()
|
AW: SIGSEGV bei öffnen einer SQL-Query
Vielen Dank für den Hinweis. Hat aber leider auch nix gebracht. Beim 20. Aufruf des Fensters kommt "External SIGSERV". Der Aufrufstack sieht wie folgt aus:
Delphi-Quellcode:
Hilft Euch das weiter? Seltsam bei #1 finde ich, daß dort MYSQLWRITEDATA$ steht. Ich schreibe gar keine Daten in die Datenbank. Habe das Fenster jeweils mit Cancel beendet.
#0 SYSTEM_SMALLFORWARDMOVE_3 at :0
#1 MYSQL51CONN_TCONNECTIONNAME_$__MYSQLWRITEDATA$crc1AADA6FD at :0 #2 MYSQL51CONN_TCONNECTIONNAME_$__LOADFIELD$TSQLCURSOR$TFIELDDEF$POINTER$BOOLEAN$$BOOLEAN at :0 #3 SQLDB_TCUSTOMSQLQUERY_$__LOADFIELD$TFIELDDEF$POINTER$BOOLEAN$$BOOLEAN at :0 #4 BUFDATASET_TCUSTOMBUFDATASET_$__LOADBUFFER$PCHAR$$TGETRESULT at :0 #5 BUFDATASET_TCUSTOMBUFDATASET_$__GETNEXTPACKET$$LONGINT at :0 #6 ?? at :0 #7 DBCTRLS_TDBLOOKUP_$__FETCHLOOKUPDATA at :0 #8 DBCTRLS_TDBLOOKUP_$__INITIALIZE$TFIELDDATALINK$TSTRINGS at :0 #9 DBCTRLS_TDBLOOKUP_$__ACTIVECHANGE$TOBJECT at :0 #10 DBCTRLS_TFIELDDATALINK_$__ACTIVECHANGED at :0 #11 DB_TDATALINK_$__CHECKACTIVEANDEDITING at :0 #12 ?? at :0 #13 DB_TDATASET_$__SETACTIVE$BOOLEAN at :0 #14 SQLDB_TCUSTOMSQLQUERY_$__SETACTIVE$BOOLEAN at :0 #15 ?? at :0 #16 MEN_TERMINEDITCLICK(0x1, 0x4c7947d) at frm_main.pas:386 #17 CONTROLS_TCONTROL_$__DBLCLICK at :0 #18 GRIDS_TCUSTOMGRID_$__DBLCLICK at :0 #19 CONTROLS_TCONTROL_$__WMLBUTTONDBLCLK$TLMMOUSE at :0 #20 SYSTEM_TOBJECT_$__DISPATCH$formal at :0 #21 CONTROLS_TCONTROL_$__WMXBUTTONDOWN$TLMMOUSE at :0 #22 CONTROLS_TWINCONTROL_$__WNDPROC$TMESSAGE at :0 #23 GRIDS_TCUSTOMGRID_$__WNDPROC$TMESSAGE at :0 #24 DBGRIDS_TCUSTOMDBGRID_$__WNDPROC$TMESSAGE at :0 #25 LCLMESSAGEGLUE_DELIVERMESSAGE$TOBJECT$formal$$LONGINT at :0 #26 WIN32INT_WINDOWPROC$LONGWORD$LONGWORD$LONGINT$LONGINT$$LONGINT at :0 #27 USER32!GetDC at :0 #28 ?? at :0 #29 USER32!GetDC at :0 #30 WIN32INT_DISPOSECOMBOEDITWINDOWINFO$TCUSTOMCOMBOBOX at :0 #31 USER32!GetWindowLongW at :0 #32 ?? at :0 |
AW: SIGSEGV bei öffnen einer SQL-Query
Nochmals vielen Dank für die Hilfe. Nach vielen Tests habe ich herausgefunden, daß das Problem nicht die SQLQuery war, sondern die TDBLookupComboBox. Die kommt mit den etwa 2000 Einträgen (manchmal) nicht klar, die die Query lieferte. Bei Begrenzung auf 100 Einträge trat der Fehler nicht mehr auf. Der Absturz trat immer dann auf (seltsamerweise wie beschrieben erst nach mehrfachem Aufruf des Fensters), wenn ich der Listsource die Datasource zugewiesen habe. Ich habe nun die LookupCombobox durch eine einfache Combobox ersetzt. Es scheint so, als wäre der Fehler nun behoben.:roll:
Damit können wir das Thema (vorerst) hoffentlich erst einmal abschließen. Auch wenn ich das eigentliche Problem nicht verstehe.....:?: |
AW: SIGSEGV bei öffnen einer SQL-Query
Würdest du eventuell bitte einen Bug im
![]() Gruß, Sven |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:52 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz