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



  • Schlangenmensch schrieb:

    Du übergibst deinem TCP Socket einen This Pointer. Der Pointer zeigt auf ein Objekt das von QThread erbt. QThread erbt von QObject, daher solltest du das nicht manuell löschen müssen.

    Vielen dank für den Hinweis.

    Schlangenmensch schrieb:

    .
    Wenn du befürchtest, dass der Fehler im TCP Bereich liegt, würde ich nochmal den Multithreading part, raus nehmen. (nicht start() aufrufen, sondern direkt die run()). Und dann schauen wo, er in der run() rausfliegt. Dann kannst du auch mit dem Debugger durch steppen.

    Wenn ich die statt start() run() nehme , dann bleibt die SW hängen

    Schlangenmensch schrieb:

    Eine andere Möglichkeit wäre, die TCP Sachen mal auszukommentieren und testen ob es dann läuft (auch wenn nichts produktives passiert). Dann solange wieder einkommentieren, bis der Fehler lokalisiert ist.

    Das habe ich gemacht.
    Wenn ich keine TCP Sachen benutze, dann lauft die SW einwandfrei.



  • Bei welchem TCP related Funktionsaufruf bleibt er denn hängen?



  • Schlangenmensch schrieb:

    Bei welchem TCP related Funktionsaufruf bleibt er denn hängen?

    Beim Object Erzeugung
    Object wird erzeugt und der Thread wird nicht mehr freigegeben.



  • Oh. Guter Hinweis und ich habe da eine blöde Vermutung.

    Du erstellst einen Thread. In dem Thread erzeugst du ein TCP Objekt auf dem Heap. Dessen Parent ist der Thread. Beim Beenden des Threads wird evt auch das TCP Objekt aufgeräumt.
    Um solche Unklarheiten zu vermeiden hatte ich vor vielen Posts schon mal geschrieben, dass ich eine extra Klasse nur für den Thread geschrieben und dann aus deinem VisaAgilent ein Thread Objekt erzeugt und mit thread.start() gestartet hätte.
    So ist mir tatsächlich grade nicht ganz klar, was passiert wenn der Thread beendet wird und wo drauf genau der this Pointer im Thread zeigt.

    Erstell das TCP Objekt mal außerhalb deines Threads, einfach um sicher zu gehen, was die Lebenszeit anbegeht.

    Wenn du hier schreibst, dass der Thread nicht mehr freigegeben wird, meinst du das der Fehler aus deinem ersten Post auftritt? Oder passiert inzwischen was anderes?

    //Edit: 2 Formulierungen angepasst.



  • Schlangenmensch schrieb:

    Oh. Guter Hinweis und ich habe da eine blöde Vermutung.

    Du erstellst einen Thread.
    In dem Thread erzeugst du ein TCP Objekt auf dem Heap.
    Dessen Parent ist der Thread.

    --> Ja

    VisaAgilent::VisaAgilent(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p, bool boDebug_p):m_SDDevPeriodeA(0), m_SDDevDCA(0),m_SDDevDCB(0),m_SDDevWidthZ(0)
    {
    
    	m_boDebug = boDebug_p;
    	m_boSimulate = boSimulate_p;
    
    	m_enRetVal = enRspOffline;
    	m_strCtrlIP = QString("");
    	m_iTimeout = 0;
    	m_iTimeoutClose = iTimeout_p;
    	if (this->Execute("CreateObject", 0, 0, 0) != enRspOK)
    	{
    		throw(QString("Error VisaAgilent.CPP/Constructor TcpSocket Create memory error"));
    	}
    
    	this->Open(strIpAdress_p, iTimeout_p);
    }
    

    Execute sieht so aus:

    Execute(....)
    {
    	....
    	start();
    	...
    }
    

    die run() sieht so aus:

    run()
    {
    ...
    	if (strcmp(m_ByteArrayWrite.constData(),"CreateObject")==0)
    	{
    		if (this->m_boSimulate == true)
    		{
    			m_enRetVal = enRspOK;
    		}
    		else
    		{
    			m_pTcpSctCtrl = new QTcpSocket(this); 
    			if (m_pTcpSctCtrl != NULL)
    			{
    				m_enRetVal = enRspOK;
    			}
    		}
    
    		boRun_l = false;
    	}
    	......
    }
    

    Schlangenmensch schrieb:

    Beim Beenden des Threads wird also auch das TCP Objekt aufgeräumt.

    Ja

    run()
    {
    	....
    	if (strcmp(m_ByteArrayWrite.constData(),"DeleteObject")==0)
    	{
    		if (this->m_boSimulate == true)
    		{
    		}
    		else
    		{
    			if (m_pTcpSctCtrl != NULL)
    			{
    				delete m_pTcpSctCtrl; // muss ich hier delete ???? 
    			}
    		}
    
    		m_enRetVal = enRspOK;
    		boRun_l = false;
    	}
    }
    
    ..
    

    Schlangenmensch schrieb:

    Um solche Unklarheiten zu vermeiden hatte ich vor vielen Posts schon mal geschrieben, dass ich eine extra Klasse nur für den Thread geschrieben und du
    dann aus deinem VisaAgilent ein Thread Objekt erzeugt und mit thread.start() gestartet hätte.

    --> Warum soll ich besser eine extra Klasse für Thread schreiben?
    --> was für einen Sinn macht das?

    Schlangenmensch schrieb:

    So ist mir tatsächlich grade nicht ganz klar, was passiert wenn der Thread beendet wird.

    --> Es muss wieder freigegeben werden

    run()
    {
    ...
    if (strcmp(m_ByteArrayWrite.constData(),"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;
    	}
    ....
    }
    

    Schlangenmensch schrieb:

    und wo drauf genau der this Pointer im Thread zeigt:

    --> lauf Qt Definition

    explicit QTcpSocket(QObject *parent = Q_NULLPTR);
    

    --> also QObject

    Schlangenmensch schrieb:

    Erstell das TCP Objekt mal außerhalb deines Threads, einfach um sicher zu gehen, was die Lebenszeit anbegeht.

    --> Das tue ich in so z.B ausserhalt der Thread:

    if(Bedingung)
    {
    	VisaAgilent DSO_l(......); // Object von typ VisaAgilent wird erzeugt
    	DSO_l.ExecuteRunControl();
    
    }
    

    Schlangenmensch schrieb:

    Wenn du hier schreibst, dass der Thread nicht mehr freigegeben wird, meinst du das der Fehler aus deinem ersten Post auftritt?

    nein.
    Es tritt keinen Fehler sondern der Thread wird nicht mehr freigegeben.
    Normalerweise es läuft so :
    Object erzeugen, dann task ausführen und beim Thread verlassen wieder freigeben.
    Wenn ich aber einen Object von Typ VisaAgilent verlasse, dann was auf dem Heap ist muss gelöscht werden.In diesem Fall m_pTcpSctCtrl

    Schlangenmensch schrieb:

    Oder passiert inzwischen was anderes?

    Nein



  • Ich glaube wir reden hier ziemlich aneinander vorbei und du hast nicht verstanden was ich meinte oder du hast Multithreading nicht richtig verstanden

    Ich versuche hier mal zu skizzieren was in deinem Programm passiert:

    Main Thread-------------thread1-----------------------------thread2
    ---|
    -Konstruktor-------------|
    -VisaAgilent-----------erstellt TCP objekt
    ---|-------------------wird beendet (was passiert
    ---|-------------------mit dem TCP Objekt
    --wartet auf
    --Thread

    ---
    -ExecuteRunControl----------------------------------------------
    -erzeugt wieder---------------------------------------------------

    -einen Tread-------------------------------------------------macht irgendwas
    ---|---------------------------------------------------------mit TCP Objekt
    ---|---------------------------------------------------------(wenn es denn noch lebt?)
    ---|--------------------------------------------------------Thread wird beendet
    -wartet auf thread

    ---

    -Destruktor
    -erzeugt wieder einen
    -Thread (den beschreibe
    -ich jetzt nicht)

    Saheb schrieb:

    --> Warum soll ich besser eine extra Klasse für Thread schreiben?
    --> was für einen Sinn macht das?

    Bessere Kapselung, klareres Verständnis was in deinem Code passiert, die Möglichkeit wirklich nebenläufig zu programmieren.

    Grobe Skizze wie ein Nebenläufiges Programm dann aussehen kann:

    • Erstelle Socket und öffne Verbindung
    • Erstelle n Threads die auf Socket schreiben/lesen (achtung gemeinsame Ressource)
    • Alle Threads haben ihre Arbeit erledigt
    • Schließe Socket
    • Programm fertig

    Edit: Mit TCP Objekt beziehe ich mich auf:

    m_pTcpSctCtrl = new QTcpSocket(this);
    

    und das findet bei dir doch im Code statt, der von start() aufgerufen wird.


Anmelden zum Antworten