[solved] QSqlDatabase & core dump

Alles rund um die Programmierung mit Qt
Antworten
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

[solved] QSqlDatabase & core dump

Beitrag von pfid »

Hallo,

ich schreibe gerade ein neues Programm, das über eine kleine GUI (abgeleitet von QMainWindow) auf eine Mysql Datenbank zugreifen soll. Qt wird in Version 4.4 genutzt.

Im Code rufe ich in einer init-Methode folgende Methode auf:

Code: Alles auswählen

   db = QSqlDatabase::addDatabase("QMYSQL");
   db.setHostName(dbHost);
   db.setDatabaseName(dbName);
   db.setUserName(dbUser);
   db.setPassword(dbPass);

   tell("Connecting to mysql database ...");

   if (!db.open())
      tell("Error: failed to connect to mysql database:\n" + db.lastError().text());
Im closeEvent:

Code: Alles auswählen

   db.close();

Wobei db eine Membervariable der GUI Klasse ist

Code: Alles auswählen

QSqlDatabase db;
Nun, die Verwendung klappt wunderbar. Ich bekomme meine TableModels gefüllt, es kommen keine Fehler usw.
Wenn ich das Programm nun beende, bekomme ich nen "Core Dump" bei Visual Studio. Er hängt im Desktruktor der GUI Klasse.

Code: Alles auswählen

-		this	0x028d5a40 {data=??? }	Cobra * const
		[QWidget]	CXX0033: Fehler: Fehler in OMF-Typinformationen	
+		QMainWindow	{...}	QMainWindow
(Cobra ist der name der GUI Klasse).

Backtrace ist

Code: Alles auswählen

 	QtCored4.dll!QAbstractItemModel::~QAbstractItemModel()  Zeile 1193 + 0xf Bytes	C++
 	QtCored4.dll!QAbstractTableModel::~QAbstractTableModel()  Zeile 2459 + 0x8 Bytes	C++
 	QtSqld4.dll!QSqlQueryModel::~QSqlQueryModel()  Zeile 171 + 0x9 Bytes	C++
 	QtSqld4.dll!QSqlTableModel::~QSqlTableModel()  Zeile 351 + 0x8 Bytes	C++
 	cobra.exe!QSqlTableModel::`scalar deleting destructor'()  + 0x10 Bytes	C++
 	QtCored4.dll!QObjectPrivate::deleteChildren()  Zeile 1860 + 0x24 Bytes	C++
 	QtGuid4.dll!QWidget::~QWidget()  Zeile 1335	C++
 	QtGuid4.dll!QMainWindow::~QMainWindow()  Zeile 329 + 0x22 Bytes	C++
>	cobra.exe!Cobra::~Cobra()  Zeile 43 + 0xac Bytes	C++
 	cobra.exe!Cobra::`scalar deleting destructor'()  + 0xf Bytes	C++
 	cobra.exe!main(int argc=1, char * * argv=0x02706eb0)  Zeile 22 + 0x21 Bytes	C++
 	cobra.exe!_WinMain@16()  + 0x128 Bytes	
 	cobra.exe!__tmainCRTStartup()  Zeile 574 + 0x35 Bytes	C
 	cobra.exe!WinMainCRTStartup()  Zeile 399	C
 	kernel32.dll!76b3e3f3() 	
 	ntdll.dll!777ecfed() 	
 	ntdll.dll!777ed1ff() 	
In der main.cpp siehts so aus:

Code: Alles auswählen

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   
   Cobra* cobra = new Cobra;

   if (cobra->atConfig() != 0)
   {
      delete cobra;
      return 1;
   }

   cobra->init();
   cobra->show();

   app.exec();

   delete cobra;

   return 0;
}

Wenn ich das db.close() im closeEvent weglasse, kommt kein Fehler. Was mache ich falsch? Habe im Code/GUI dann noch 2 TableViews mit entsprechendem SqlTableModel. Muss ich da beim abbauen/löschen irgendwas spezielles beachten?
Zuletzt geändert von pfid am 24. Juli 2008 10:13, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ich denke nicht das db als Member-Variable so gut ist. Dafür gibt es eigentlich QSqlDatabase::database
Und so wie es aussieht setzt Du vor dem close() dein SqlTableModel nicht zurück - d.h. es wird nach dem close() noch irgendwie drauf zugegriffen. Setze mal vor dem close() ein leere Model und schau ob der Crash dann immer noch da ist.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Hm, also model->clear() hat auch nichts gebracht. Der Backtrace sieht jetzt ein wenig anders aus, ansonsten ist es gleich.

Ich würde die QSqlDatabase Geschichten ja in die main.cc packen, aber die Konfiguration für die Datenbank wird halt über die GUI Klasse aus der .ini Datei gelesen. Würde zwar trotzdem gehn, indem ich der GUI Klasse die entsprechenden Getter verpasse, aber sieht für mich umständlich und unschön aus.

Wie ist denn die normale vorgehensweise, wenn meine Qt Applikation eine Datenbank nutzen will?

Hab jetzt noch nen anderen Versuch gemacht, der scheint so halb zu klappen.

main.cc:

Code: Alles auswählen

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   
   QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

   Cobra* cobra = new Cobra;

   if (cobra->atConfig() != 0)
      return 1;

   cobra->init();
   cobra->show();

   app.exec();

   delete cobra;

   db.close();

   return 0;
}
in der Klasse:

Code: Alles auswählen

   db = QSqlDatabase::database();
   db.setHostName(dbHost);
   db.setDatabaseName(dbName);
   db.setUserName(dbUser);
   db.setPassword(dbPass);
Es kommt kein core dump, der Datenbankzugriff funktioniert (es sind Daten in den Models), aber während dem Starten kommt in der Konsole:

Code: Alles auswählen

QSqlDatabasePrivate::database: unable to open database: Can't connect to MySQL server on 'localhost' (10061) QMYSQL: Unable to connect
Werd ich irgendwie nicht schlau draus.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Das "QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");" kannst Du doch auch erst später machen. Machst Du ggf. ein db.open() bevor die connection richtig aufgebaut wurde?
Ich würde der DB-Connection noch einen Namen geben damit sie darüber ansprechbar ist.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Also ich denke ich habe hier ein größeres Problem. Habe eben mal den Code auf Arbeit angeschaut (da nutzen wir auch ein Qt-basiertes Programm mit Sql-Anbindung), da wird genauso vorgegangen wie im letzten Post beschrieben.

Ausserdem ist mir aufgefallen, dass ich kein submitAll() ausführen kann. Selbst wenn im Table nur eine Row mit richtigen Datentypen steht, schlägt submitAll() mit einem Binding-Fehler (falscher Datenpuffer o.ä., habs nicht im Kopf) fehl. Ich vermute es liegt an meiner Qt Installation. Ich glaube nämlich dass ich (leider) die Prebuild-Version installiert habe, die im Forum von www.c-plusplus.de angeboten wurde. Entweder habe ich die falsche installiert, oder die Mysql Komponente dort ist veraltet. Denn ein wenig googeln nach dem submitAll() Fehler hat ergeben, dass es wohl daher kommen könnte, dass die Mysql-Lib die zum Bauen von Qt verwendet wurde zu alt ist.
jedenfalls werde ich heute abend erstmal Qt neu bauen. Zu allem Überfluss schmiert der VC Compiler direkt bei jedem Configure-Aufruf von Qt ab, so dass ich auch erstmal VC neu installieren darf. (googeln hat ergeben dass es wohl an ner defekten Net-Installation von VC liegen kann [obwohl bislang keine fehler kamen]. werde daher die DVD (3gb) laden und nochmal komplett VC installieren).

Wenn das erledigt ist, kann ich (hoffentlich) Qt mit der neusten Mysql-Lib bauen. Mal sehn ob das was bringt.



Okay, die Neuinstallation von VC2008 hat nichts gebraucht, ich kann Qt immer noch nicht kompilieren. Beim Aufruf

configure.exe -platform win32-msvc2008 -qt-sql-mysql

bekomme ich direkt den Fehler:
"Microsoft C/C++ Compiler Driver funktioniert nicht mehr. [Online Lösung suchen][Schließen]"

bei

Code: Alles auswählen

Microsoft (R) Program Maintenance Utility, Version 9.00.21022.08
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.

        cl -c -Foproject.obj  -W3 -nologo -O2  -I. -Igenerators -Igenerators\uni
x -Igenerators\win32 -Igenerators\mac  -ID:\source\sdk\qt\qt\include -ID:\source
\sdk\qt\qt\include\QtCore  -ID:\source\sdk\qt\qt\include -ID:\source\sdk\qt\qt\i
nclude\QtCore  -ID:\source\sdk\qt\qt\src\corelib\global  -ID:\source\sdk\qt\qt\i
nclude\QtScript  -ID:\source\sdk\qt\qt\mkspecs\win32-msvc2008   -DQT_NO_TEXTCODE
C -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL  -DQT_NO_COMP
RESS -DUNICODE -DHAVE_QCONFIG_CPP -DQT_BUILD_QMAKE -DQT_NO_THREAD  -DQT_NO_QOBJE
CT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM -DQT_NO_PCRE -DQT_BOOTSTRAPPED   -DQM
AKE_OPENSOURCE_EDITION project.cpp [...]
Hat jemand ne Ahnung was das sein könnte?

:(


[edit] Hat sich alles erledigt. Nach VS neu installieren, Qt mit aktueller Mysql Lib bauen hat dann alles funktioniert. Die Meldung kommt nicht mehr, und model->submit() funktioniert auch.
Das Datenbankobjekt wird jetzt in main.cc hinzugefügt, in der Cobra-Klasse geöffnet, und in der main.cc nach dem Löschen der Cobra Klasse wieder geschlossen.
Antworten