[gelöst]flush() bewirkt programmabsturz (QT4/OGRE)

Alles rund um die Programmierung mit Qt
Antworten
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

[gelöst]flush() bewirkt programmabsturz (QT4/OGRE)

Beitrag von kallitokaco »

Moin

Ich hab ein Problem mit flush() von einem TCPsocket unter WinXP(32Bit) mit Visual Studio Express 2005.

Ich verwende QT4.4 mit OGRE zusammen, ich denke das OGRE den Fehler irgendwie auslößt, bin mir aber überhaupt nicht sicher.
(OGRE: eine 3d grafikengine --> http://www.ogre3d.org)
Ich lasse mal alle Daten die nicht interressiern weg.

e_Client.cpp (in meinem fall die "Startdatei"):

Code: Alles auswählen

#include "e_Scene.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
	Scene app;
	//in der Klasse Scene  liegt der Fehler
    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
        std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
    }

    return 0;
}

#ifdef __cplusplus
}
#endif
e_Scene.h

Code: Alles auswählen

#ifndef E_SCENE_H
#define E_SCENE_H
#include "e_Anwendung.h"
#include "e_chara.h"
#include "stdio.h"
#include <QList>
#include "e_socket.h"
class Scene : public ExampleApplication 
{
public:
    Scene();
    ~Scene(); 
	
	//Funktionen
	...
	
	//Variablen
	QList<chara *> charlist;
	SceneNode *node;
	Client socket; // <-- der socket der das Problem, hat
protected:
    ...
	
};
#endif
e_Scene.cpp


Code: Alles auswählen

#include "e_Scene.h"
#include <QDebug>
//Funktionen
...




    Scene::Scene()
    {
		//Login darstellen fehlt
		qDebug() << "login";
		socket.login("ADMIN","test");
    }

    Scene::~Scene() 
    {
    }

   ...

e_socket.h

Code: Alles auswählen

#ifndef E_SOCKET_H
#define E_SOCKET_H

#include <QTcpSocket>
#include <QObject>
class QTcpSocket;

class Client: public QObject
{
    Q_OBJECT

public:
    Client();
    void send(quint16 hd,QString data="");
    void send(quint16 hd,qint32 hd2,QString data="");
    void send(quint16 hd,qint16 hd2,QString data="");
    void send(quint16 hd,qint8 hd2,QString data="");
    void send(quint16 hd,bool hd2,QString data="");
    void send(quint16 hd,qint32 hd2,qint32 hd3,QString data="");
	void login(QString user, QString password);
public slots:
    
    void connectToHost();
    void read();
    void dc();
    void displayError(QAbstractSocket::SocketError socketError);
    void senderhalten();

private:
    QTcpSocket *tcpSocket;
    QString text;
    QString id;
    quint16 blockSize;
};

#endif
e_socket.cpp

Code: Alles auswählen



#include <QtGui>
#include <QtNetwork>
#include <string>

#include "e_socket.h"

Client::Client()
{
    

    
    tcpSocket = new QTcpSocket(0);

    
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(read()));
    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(dc()));
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
    //connect(textLineEdit, SIGNAL(returnPressed ()),
    //        this, SLOT(sendtext()));
    

    
    qDebug() << "-->gestartet";
    
    blockSize = 0;
    tcpSocket->abort();
    tcpSocket->connectToHost("192.168.1.2",3333);
    qDebug() << "-->connected";
}

...

void Client::login(QString user, QString password)
{
    send(2,user.size(),user + password);
    
}

...

void Client::send(quint16 hd,qint32 hd2,QString data)
{
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_4);
    out << quint16(0);
    //out << QString("test:");
    out << quint16(hd);
    out << qint32(hd2);
    out << data;
    out.device()->seek(0);
    out << quint16((block.size() - sizeof(quint16)));

    tcpSocket->write(block);
    //tcpSocket->flush();
    //lblStatus->setText(data);
    qDebug() << "Senden von " << data;
}
void Client::send(quint16 hd,qint16 hd2,QString data)
{
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_4);
    out << quint16(0);
    //out << QString("test:");
    out << quint16(hd);
    out << qint16(hd2);
    out << data;
    out.device()->seek(0);
    out << quint16((block.size() - sizeof(quint16)));

    tcpSocket->write(block);
    //tcpSocket->flush();
    //lblStatus->setText(data);
    qDebug() << "Senden von " << data;
}
... 
alle send(...) sehel im grunde gleich aus
so wie der code hier zu sehen ist, also die flush() auskommentiert , funktioniert er. Allerdings mit flush() nichtmehr und ohne flush() sendet der keine daten, sondern conected nur zum server, was allerdings einbahnfrei klappt.

Das größte Problem ist, dass ich keine Fehlermeldung bekomme zumindest ist es für mich keine:

Code: Alles auswählen

Der Thread 'Win32 Thread' (0x6e4) hat mit Code 0 (0x0) geendet.
Das Programm "[3164] Client.exe: Systemeigen" wurde mit Code 0 (0x0) beendet.
Das Programm fängt nochnichtmals an zu laufen, d.h wenn ich in der Main() ganz oben über Scene app; ein printf oder qDebug oder so machen bekomm ich keine Ausgabe davon.(Mit auskommentiertem flush() werd ich mit qDebug() zugeschüttet.)
(Übrigens klappt der server sowie die funktionen aus der e_socket.h/cpp auf der selben plattform nur ohne OGRE und mit einem QTGUI einbahnfrei....)

Weiß einer woran das liegen könnte?

Ich wäre echt sehr dankbar für hilfe.

Viele dank

Kallitokaco
Zuletzt geändert von kallitokaco am 25. Juli 2008 12:10, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Im Debugger laufen lassen und den Backtrace anschauen.

Des weiteren ist

Code: Alles auswählen

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
falsch.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

Beitrag von kallitokaco »

Im degugger steht folgendes:

Code: Alles auswählen

"Client.exe": "C:\Dokumente und Einstellungen\Kallitokaco\Desktop\Neuer Ordner\Client\Client\bin\debug\Client.exe" geladen, Symbole wurden geladen.
"Client.exe": "C:\WINDOWS\system32\ntdll.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\kernel32.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\Dokumente und Einstellungen\Kallitokaco\Desktop\Neuer Ordner\Client\Client\bin\debug\OgreMain_d.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\user32.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\gdi32.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_5490cd9f\msvcp80d.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_5490cd9f\msvcr80d.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\msvcrt.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\Dokumente und Einstellungen\Kallitokaco\Desktop\Neuer Ordner\Client\Client\bin\debug\OIS_d.dll" geladen, Die Binärdaten wurden nicht mit Debuginformationen erstellt.
"Client.exe": "C:\WINDOWS\system32\dinput8.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\advapi32.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\rpcrt4.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\secur32.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\QtCored4.dll" geladen, Symbole wurden geladen.
"Client.exe": "C:\WINDOWS\system32\ole32.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\ws2_32.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\ws2help.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\QtNetworkd4.dll" geladen, Symbole wurden geladen.
"Client.exe": "C:\WINDOWS\system32\imm32.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\mswsock.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\hnetcfg.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\wshtcpip.dll" geladen, Keine Symbole geladen.
Eine Ausnahme (erste Chance) bei 0x7c812a5b in Client.exe: Microsoft C++-Ausnahme: Ogre::FileNotFoundException an Speicherposition 0x0012ee64..
Eine Ausnahme (erste Chance) bei 0x7c812a5b in Client.exe: Microsoft C++-Ausnahme: Ogre::FileNotFoundException an Speicherposition 0x0012f4d8..
"Client.exe": "C:\WINDOWS\system32\uxtheme.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\MSCTF.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\version.dll" geladen, Keine Symbole geladen.
"Client.exe": "C:\WINDOWS\system32\version.dll" entladen.
"Client.exe": "C:\WINDOWS\system32\MSCTFIME.IME" geladen, Keine Symbole geladen.
Der Thread 'Win32 Thread' (0x6e4) hat mit Code 0 (0x0) geendet.
Das Programm "[3164] Client.exe: Systemeigen" wurde mit Code 0 (0x0) beendet.
Des weiteren ist
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
falsch.
Was ist denn daran falsch? es tut zumindest auf Linux und windows mehr hab ich noch nicht ausprobiert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ich wollte den Backtrace, nicht die Debug-Ausgaben.

Es muss immer

Code: Alles auswählen

int main(int argc, char**argv)
sein. Unter Windows wie unter Linux. Wenn Du WinMain unter Windows + Qt überschreibst ist das nicht so gut.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

Beitrag von kallitokaco »

ich hoffe das ist das was du suchst:

Code: Alles auswählen

>	QtNetworkd4.dll!QAbstractSocket::error(QAbstractSocket::SocketError _t1=UnfinishedSocketOperationError)  Zeile 144	C++
 	QtNetworkd4.dll!QAbstractSocketPrivate::flush()  Zeile 679	C++
 	QtNetworkd4.dll!QAbstractSocket::flush()  Zeile 1802	C++
 	Client.exe!Client::send(unsigned short hd=2, int hd2=5, QString data={...})  Zeile 178 + 0xe Bytes	C++
 	Client.exe!Client::login(QString user={...}, QString password={...})  Zeile 46	C++
 	Client.exe!Scene::Scene()  Zeile 67	C++
 	Client.exe!WinMain(HINSTANCE__ * hInst=0x00400000, HINSTANCE__ * __formal=0x00000000, char * strCmdLine=0x00151f45, HINSTANCE__ * __formal=0x00000000)  Zeile 18 + 0x8 Bytes	C++
 	Client.exe!__tmainCRTStartup()  Zeile 578 + 0x35 Bytes	C
 	Client.exe!WinMainCRTStartup()  Zeile 403	C
 	kernel32.dll!7c816fd7() 	
 	[Unten angegebene Rahmen sind möglicherweise nicht korrekt und/oder fehlen, keine Symbole geladen für kernel32.dll]	
Allerdings hab ich dafür mit F11 solang weltergemacht bis an der Stelle war und sagte das der Quellcode nicht zur verfügung stehen würde. Dannach ist der einfach gestoppt bzw. aus dem debugmodus gegangen.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Mach mal einen Breakpoint in displayError() - dort müsstest Du dann sehen was genau das für ein Fehler ist. Ich kann nur sehen dass das Schreiben schief geht. Ging evtl. das open() schief? Überprüf bitte den Rückgabewert dieser Funktion.
Und bitte nimm das WinMain raus - Qt mact in dieser Funktion einige Initialisierungen die sonst fehlen - siehe qt4-src/src/winmain/winmain.cpp
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

Beitrag von kallitokaco »

Code: Alles auswählen

bool QAbstractSocketPrivate::flush()
{
    Q_Q(QAbstractSocket);
    if (!socketEngine || !socketEngine->isValid() || writeBuffer.isEmpty()) {
#if defined (QABSTRACTSOCKET_DEBUG)
    qDebug("QAbstractSocketPrivate::flush() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s",
           socketEngine->isValid() ? "yes" : "no", writeBuffer.isEmpty() ? "yes" : "no");
#endif
        return false;
    }

    int nextSize = writeBuffer.nextDataBlockSize();
    const char *ptr = writeBuffer.readPointer();

    // Attempt to write it all in one chunk.
    qint64 written = socketEngine->write(ptr, nextSize);
    if (written < 0) {
        socketError = socketEngine->error();
        q->setErrorString(socketEngine->errorString());
        emit q->error(socketError);
        // an unexpected error so close the socket.
Zeile 655 in qabstaktsocket.cpp

bei if (written < 0) { ist der fehler, der erste und der schließt das socket

übrigens wenn ich WINMAIN weg mache läuft ogre nicht ogre brauch die für das directX zeug, denk ich.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wie 'läuft Ogre nicht' - WinMain macht doch gar nichts...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

Beitrag von kallitokaco »

Wenn ich das nicht benutze bekomm ich folgendes:

Code: Alles auswählen

1>MSVCRTD.lib(crtexew.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_WinMain@16" in Funktion "___tmainCRTStartup".
1>bin\Debug\Client.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.
Ich weis zwar nicht wieso das da sein muss, aber es schließlich in eig. allen Ogre sachen so. Wird ja schon seinen Grund haben, auch wenn ich noch nicht weiß wieso, bin noch nicht lang mit OGRE am arbeiten.
Mein Client nutzt QT nur fürs netzwerk und n paar berechnungen, keine fenster oder so werden genutzt und in der qtmain_win.cpp steht ja das WinMain nicht aufgerufen wird wenn eine consolenanwendung gelinkt wird.

könnte es evtl. sein das der fehler wegen der änderung in qglobal.h(794) sein:

Code: Alles auswählen

#ifndef OGRE_VERSION
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
#endif
hab nur das ifndef drum herum gelegt , da OGRE leider exakt die gleichen definitionen verwendet und bisjetz alles andere einbahnfrei lief. Ich hab noch nie ein flush() mit einem tcpsocket gemacht und ogre dabei genutzt, aber sollte der Fehler nicht schon früher auftauchen?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Oge macht immer den Müll mit WinMain - warum auch nicht, auf alle Fälle ist es falsch.
Unter Windows musst Du noch gegen qtmain(d) linken (was , wenn man make benutzt automatisch passiert). Und das ist wichtig!

Man sollte nicht in Qt-Headern rumpfuschen... Wie definiert ogre diese Datentypen?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

Beitrag von kallitokaco »

bei ogre siehts genau so aus:

preguisites.h(130)

Code: Alles auswählen

   typedef unsigned char uchar;
    typedef unsigned short ushort;
    typedef unsigned int uint;
	typedef unsigned long ulong;
Allerdings mekert OGRE wenn ich das auskommentiere, QT nicht.

QTmain? ich hab nur Qtcore4(d).lib qtnetwork(d)4.lib und die qtgui(d)4.lib und so die bei dem visual studio linker eigetragen sind, die meinste doch oder?

edit:
die sind beim linker eingetragen(debug) aber die Qtmain fehlt, die gibt es aber auch nicht, wenn ich das mit qmake mache:

Code: Alles auswählen

OgreMain_d.lib OIS_d.lib qtcored4.lib qtnetworkd4.lib qtguid4.lib
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wenn Du mit qmake ein app-Projekt baust wird qtmain(d).lib mit hinzugefügt. Und wenn es bei Dir nicht ist, kommt natürlich der Linkerfehler.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

Beitrag von kallitokaco »

ah ok thx jetz kommt zumindest wieder ne ordentliche fehlermeldung + qDebug, wenn winmain auskommentiert ist.

Code: Alles auswählen

-->connected 
login 
QNativeSocketEngine::write() was not called in QAbstractSocket::ConnectedState
Der Thread 'Win32 Thread' (0xb3c) hat mit Code 0 (0x0) geendet.
Das Programm "[1484] Client.exe: Systemeigen" wurde mit Code 0 (0x0) beendet.

wo der genau das problem hat schau ich morgen/in wenigen stunden nach wenn ich wieder wacher bin.

Vielen Vielen Dank für die Hilfe bis jetz.


gn8
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Prima :)

Und es war auch das was ich vermutete - das Connect ging schief bzw. wurde nicht ausgeführt.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

Beitrag von kallitokaco »

jup du hattest recht.
Ein einfaches :

Code: Alles auswählen

tcpSocket->waitForConnected(2000)

hat das letzte Problem gelößt.
Also war es nur die qtmain.lib die fehlte und das WinMain() was nicht dahin gehörte^^.

1000x Danke, ich hätte alleine ewig dafür gebraucht, wenn nicht noch länger^^

Vielen Vielen Dank


Kallitokaco
Antworten