Application.exe has triggered a breakpoint Visual Studio 2015 C++





  • könnte dann auch mit Threadprobleme zu tun haben

    was soll das?

    m_MtxProcess.lock(); 
            m_WaitCondProcess.wait(&m_MtxProcess,-1); 
            m_MtxProcess.unlock();
    


  • Beim Object create ist alles Okay.
    Problem ist wenn ich das Object schliessen möchte "CloseConnection" und genau gesagt beim:

    VisaAgilent::t_enRspType VisaAgilent::Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p)
    {
    ....
    start(); // Thread start
    ...
    }
    

    Thread landet ne in diesem Stand beim:

    void VisaAgilent::run()
    {
      .....
        if (strcmp(m_ByteArrayWrite.data(),"CloseConnection")==0)
        {
            if (this->m_boSimulate == true)
            {
                m_enRetVal = enRspOK;
            }
            else
            {
                m_pTcpSctCtrl->disconnectFromHost();
                if ((m_pTcpSctCtrl->state() == QAbstractSocket::UnconnectedState) || (m_pTcpSctCtrl->waitForDisconnected(m_iTimeout)))
                {
                    m_enRetVal = enRspOK;
                }
            }
    
            boRun_l = false;
        }
    .....
    }
    


  • Gast3 schrieb:

    könnte dann auch mit Threadprobleme zu tun haben

    was soll das?

    m_MtxProcess.lock(); 
            m_WaitCondProcess.wait(&m_MtxProcess,-1); 
            m_MtxProcess.unlock();
    

    Prozess wieder freigeben sonst bleibt so hängend



  • Problem ist wenn ich das Object schliessen möchte "CloseConnection" und genau gesagt beim:

    d.h. du hast doch mehr Informationen zu deinem Absturz?

    Ich denke du hast irgendwelche Synchronisationsprobleme mit deinen Threads

    m_MtxProcess.lock(); 
    m_WaitCondProcess.wait(&m_MtxProcess,-1); 
    m_MtxProcess.unlock();
    

    Der Code sieht komisch aus - ist dir 101% klar was du da machst? bist du Fit mit Threads?

    Bei Threadproblemen ist es ABSOLUT vorbei mit Ausprobieren-bis-es-läuft
    sonst kommst du genau in die Probleme rein die du gerade hast



  • Gast3 schrieb:

    Problem ist wenn ich das Object schliessen möchte "CloseConnection" und genau gesagt beim:

    d.h. du hast doch mehr Informationen zu deinem Absturz?

    Ich denke du hast irgendwelche Synchronisationsprobleme mit deinen Threads

    m_MtxProcess.lock(); 
    m_WaitCondProcess.wait(&m_MtxProcess,-1); 
    m_MtxProcess.unlock();
    

    Ich glaube eher nicht, da ich eigentlich auf die Sunchronisation genau geachtet habe sonst hätte auch die Relase Version, was nicht der Fall ist.
    Unter Visual Studio 2008 habe ich das Problem nicht.

    Gast3 schrieb:

    Der Code sieht komisch aus - ist dir 101% klar was du da machst?

    zu 99.9 ja

    Gast3 schrieb:

    bist du Fit mit Threads?

    Geht so

    Gast3 schrieb:

    Bei Threadproblemen ist es ABSOLUT vorbei mit Ausprobieren-bis-es-läuft
    sonst kommst du genau in die Probleme rein die du gerade hast

    Warum erst jetzt und nur in Debug Version und nur unter VStudio 2015?



  • sonst hätte auch die Relase Version, was nicht der Fall ist.

    Unter Visual Studio 2008 habe ich das Problem nicht.

    Warum erst jetzt und nur in Debug Version und nur unter VStudio 2015?

    Weil UB ein Biest ist und genau solche Effekte zeigt - und viele Entwickler einfach jahrelang schlechten Code schreiben der leider doch gut genug funktioniert und sich dabei ein falsches Selbstvertrauen aufbaut - bis man dann mal wirklich auf solche Probleme stößt - falls es sowas ist, und du es findest ist das ein ziemlicher Aha-Effekt

    Debug und Release haben anderes Zeitverhalten, der VS2008 Kompiler generiert ganz anderen Code

    wenns unter Linux kompiliert würde ich SOFORT den UB-Sanitizer, Thread-Sanitizer und den Address-Sanitizer nutzen - sind per Parameter beim Kompiler aktivierbar das sind zur Zeit die besten Tools die es gibt - da kommt nichts ran

    unter Windows könntest du die Trial-Version vom Intel-Inspector (https://software.intel.com/en-us/intel-inspector-xe) drauflassen
    vielleicht sieht du da etwas - es kann aber sein das du Problem-Meldungen bekommst die nicht wirklich Fehler sind - das ist bei den Linux-Tools so gut wie nicht der Fall



  • @ Danke

    was ich erst mal sicher bin, dass das Problem genau in diese

    class VisaAgilent
    

    ist.

    Das zu finden ist .....



  • deswegen die genannten Tools - die Linux-Varianten sind unschlagbar, der Intel Inspector wohl am einfachsten ausprobierbar - Install und im VStudio einen Knopf drücken



  • Stelle sicher, dass der Thread sich selbst beendet und du ihn nicht dazu zwingst. Auch sind diese Ganzen Konstrukte um new/delete, lock/unlock, strcmp, typedef enum/struct, NULL etc. nicht zu empfehlen oder veraltet, benutz' doch std::string, std::unique_ptr, std::async, std::lock_guard etc. Damit schließt du schonmal unbeabsichtigte Fehler aus.



  • m_MtxProcess.lock();
    m_WaitCondProcess.wait(&m_MtxProcess,-1);
    m_MtxProcess.unlock();
    

    Auf was wartest du denn hier? Ich gehe mal davon aus, dass m_WaitCondProcess vom Typ QWaitCondition ist.

    Wo rufst du das dazu gehörende wakeOne() oder wakeAll() auf?
    Den zweiten Parameter kannst du dir da sparen. Die Doku sagt, dass es sich um ein unsigned long handelt. -1 dürfte dann ULONG_MAX sein, was laut Doku nie in einem Timeout landet und default verhalten ist...



  • Schlangenmensch schrieb:

    m_MtxProcess.lock();
    m_WaitCondProcess.wait(&m_MtxProcess,-1);
    m_MtxProcess.unlock();
    

    Auf was wartest du denn hier? Ich gehe mal davon aus, dass m_WaitCondProcess vom Typ QWaitCondition ist.

    Ich warte bis der thread "run" fertig ist
    ja ist sie auch.

    Schlangenmensch schrieb:

    Wo rufst du das dazu gehörende wakeOne() oder wakeAll() auf?
    Sorry das habe ich vergessen miteinzufügen:

    void VisaAgilent::run()
    {
        bool boRun_l = true;
        bool boSent_l = false;
    
        const char *pStrCmd_l = NULL;
        const char *pStrRsp_l = NULL;
    
        m_enRetVal = enRspError;
    
        if (strcmp(m_ByteArrayWrite.data(),"CreateObject")==0)
        {
            if (this->m_boSimulate == true)
            {
                m_enRetVal = enRspOK;
            }
            else
            {
                m_pTcpSctCtrl = (QTcpSocket *)new QTcpSocket;
                if (m_pTcpSctCtrl != NULL)
                {
                    m_enRetVal = enRspOK;
                }
            }
    
            boRun_l = false;
        }
    
        if (strcmp(m_ByteArrayWrite.data(),"DeleteObject")==0)
        {
            if (this->m_boSimulate == true)
            {
            }
            else
            {
                if (m_pTcpSctCtrl != NULL)
                {
                    delete m_pTcpSctCtrl;
                }
            }
    
            m_enRetVal = enRspOK;
            boRun_l = false;
        }
    
        if (strcmp(m_ByteArrayWrite.data(),"OpenConnection")==0)
        {
            if (this->m_boSimulate == true)
            {
                m_enRetVal = enRspOK;
            }
            else
            {
                m_pTcpSctCtrl->connectToHost(m_strCtrlIP,5025);
                if (m_pTcpSctCtrl->waitForConnected(m_iTimeout) == true)
                {
                    m_enRetVal = enRspOK;
                }
            }
    
            boRun_l = false;
        }
    
        if (strcmp(m_ByteArrayWrite.data(),"CloseConnection")==0)
        {
            if (this->m_boSimulate == true)
            {
                m_enRetVal = enRspOK;
            }
            else
            {
                m_pTcpSctCtrl->disconnectFromHost();
                if ((m_pTcpSctCtrl->state() == QAbstractSocket::UnconnectedState) || (m_pTcpSctCtrl->waitForDisconnected(m_iTimeout)))
                {
                    m_enRetVal = enRspOK;
                }
            }
    
            boRun_l = false;
        }
        .....
    	QThread::msleep(m_iResponseDelayed);
    
    	QMutexLocker locker(&m_MtxProcess);
    
    	m_WaitCondProcess.wakeOne();
        }
    


  • wofür der frei stehende

    QMutexLocker locker(&m_MtxProcess);
    

    in Zeile 84? Was soll der machen?



  • Ah, dein Erzeuger Prozess wartet auf das Wakeup aus dem erstellten Thread?? Ungewöhnlich und habe ich noch nicht so gesehen. Normalerweise wartet ein Thread darauf, dass er vom Ersteller oder einen anderen Thread abgeholt wird.

    Wie rufst du die Funkionen deines VisaAgilent denn auf?
    Du musst da doch irgendwie sowas haben:

    main(){
    VisaAgilent = agilent(...); // ruft Konstruktor auf und erstellt ersten Thread. Wartet bis der Fertig ist
    agilent.open(); //Open connection-> erstellt auch einen Thread. Wartet auch bis der fertig ist.
    } // Destruktor -> erstellt auch einen Thread, wartet wieder bis der fertig ist.
    

    So hast du nie einen wirklich nebenläufigen Programmablauf (oder habe ich was total übersehen???)

    Deine unterschiede zwischen Debug und Release wird in deinem Fall wahrscheinlich darauf zurückzuführen sein, dass Destruktoren schon mal weg optimiert werden dürfen.



  • Gast3 schrieb:

    wofür der frei stehende

    QMutexLocker locker(&m_MtxProcess);
    

    in Zeile 84? Was soll der machen?

    Hier stelle ich sicher, dass der Prozess freigegeben wird, wenn das Object gelöscht wird.



  • Hier stelle ich sicher, dass der Prozess freigegeben wird, wenn das Object gelöscht wird.

    wofür das lock wenn du nichts veränderst?

    oder ist der Code den du zeigst unvollständig?



  • Schlangenmensch schrieb:

    Ah, dein Erzeuger Prozess wartet auf das Wakeup aus dem erstellten Thread?? Ungewöhnlich und habe ich noch nicht so gesehen. Normalerweise wartet ein Thread darauf, dass er vom Ersteller oder einen anderen Thread abgeholt wird.

    Wie rufst du die Funkionen deines VisaAgilent denn auf?
    Du musst da doch irgendwie sowas haben:

    main(){
    VisaAgilent = agilent(...);
    

    // ruft Konstruktor auf und erstellt ersten Thread. Wartet bis der Fertig ist

    agilent.open();}
    

    //Open connection-> erstellt auch einen Thread. Wartet auch bis der fertig ist.
    // Destruktor -> erstellt auch einen Thread, wartet wieder bis der fertig ist.

    Fast
    anbei einen Codeabschnit:

    VisaAgilent DSO_l(.....);/* Object referenzieren*/
    DSO_l.open(); //Bis hier ist alles gut
    // wenn es z.b open verlassen wird also Object "DSO_l" verlassen, wird dann das Destructor aufgerufen und da kracht warum ? --> weiss ich nicht
    

    Schlangenmensch schrieb:

    So hast du nie einen wirklich nebenläufigen Programmablauf (oder habe ich was total übersehen???)

    Deine unterschiede zwischen Debug und Release wird in deinem Fall wahrscheinlich darauf zurückzuführen sein, dass Destruktoren schon mal weg optimiert werden dürfen.



  • Gast3 schrieb:

    Hier stelle ich sicher, dass der Prozess freigegeben wird, wenn das Object gelöscht wird.

    wofür das lock wenn du nichts veränderst?

    oder ist der Code den du zeigst unvollständig?

    Sorry ich verstee nicht welchen lock meinst du ?



  • Ich sehe grade, dass open auch schon aus dem Konstruktor aufgerufen wird.

    Aber du wirst deinen Code vollständiger posten müssen, aber bitte auf das reduziert, was nötig ist um den Fehler zu reproduzieren.

    Der Destruktor von DSO_l wird aufgerufen, wenn du den Scope verlässt in dem du das erstellt hast. Wobei ich, wie gesagt, davon ausgehe, dass der im Release Modus möglicherweise gar nicht aufgerufen wird.



  • Sorry ich verstee nicht welchen lock meinst du ?

    in deinen Beispiele hier im Forum, Zeile 84


Anmelden zum Antworten