TClient/Server Socket und BCB Debugger nuked Winsock



  • audacia schrieb:

    []im public-Sichtbarkeitsbereich deklariert man keine Variablen.
    [
    ]Du setzt die Member-Variable Memo in Button1Click() auf ein Memo-Element des Formulares. Im Destruktor von TSocketTest gibst du das Memo frei - was du gar nicht darfst, da es dem Formular gehört. Daß das nichts bewirkt, liegt an Punkt 1.
    [*]Anstelle von Zeigern und delete solltest du Smart-Pointer benutzen.[/list]

    Warum? Ich definier ja in der Klasse ein Object was das Memo vom Form als referenz hat.

    Und das mit Variablen im Publicbereich, dass weiss ich - ist nur ein Testprojekt.

    In meinen "normalen" Klassen hab ich meine Set/Get Funktionen, aber das ist jetzt erstmal uninteressant da ich gern diesen *zensiert* "Bug" loswerden will 😞



  • So, ein Versuch noch 😃

    Weiss wirklich niemand was darüber? Es ist momentan schwer das Programm zu debuggen wenn man den Rechner immer starten muss 😞



  • Hast du wenigstens schon mal die ganzen Null-Zuweisungen in den Destruktoren entfernt?



  • Braunstein schrieb:

    Hast du wenigstens schon mal die ganzen Null-Zuweisungen in den Destruktoren entfernt?

    Hab ich schon längst. Der Code oben war der letzte wo ich versucht habe das "einzugrenzen" - aber bisher nach wie vor ohne Erfolg. Die letzten Tage hab ich damit verbracht um andere Teile von meinem Projekt zu schnitzen.

    Wobei ich bei manchen kleineren Teilen nicht darum gekommen bin den "nuke" in kauf zu nehmen, d.h. Programmtest, Winsock Nuke, reboot - weiter 😞



  • Was genau passiert denn jetzt? Kommt die Exception noch und wenn ja welche? Bist du mit dem Debugger mal schrittweise durchgegangen um rauszukriegen wo genau was passiert?
    Hast du mal versucht ein Minimalprojekt zu basteln was den Fehler reproduzieren kann?



  • Braunstein schrieb:

    Was genau passiert denn jetzt?

    Steht doch im ersten Post.

    Braunstein schrieb:

    Kommt die Exception noch und wenn ja welche?

    Die Exception kommt wieder bzw. wird wieder angezeigt (hab die IDE neu installiert):

    MessageBox:

    Im Projekt WinsockTest.exe ist eine Exception der Klasse EAccessViolaten mit der Meldung 'Zugriffsverletzung' aufgetreten.

    Im Ereignisprotkoll von der IDE:

    Erste Gelegenheit für Exception bei $76A342EB. Exception-Klasse EAccessViolation mit Meldung 'Zugriffsverletzung'. Prozess WinsockTest.exe (5928).

    Die Exception scheint immer "nur" dann zu kommen wenn ich SetActive aufgerufen habe, d.h. wennd er Socket dann verbunden ist.

    if (active) ClientSocket->Active = true;
    	else
    	{
    		if (ClientSocket->Socket->Connected)
    		{
    			ClientSocket->Active = false;
    //			ClientSocket->Socket->Disconnect(0);
    //			ClientSocket->Socket[0].Disconnect(0);
    //			ClientSocket->Socket[0].Close();
    			ClientSocket->Socket->Close();
    //			ClientSocket->Socket->CleanupInstance();
            }
    	}
    

    Ist der aktuellste Test gewesen (um den Socket zu trennen etc.), auch die ausmarkierten Zeilen bringen nix. (war lediglich Test obs was bringt oder nicht).

    Braunstein schrieb:

    Hast du mal versucht ein Minimalprojekt zu basteln was den Fehler reproduzieren kann?

    Steht eigentlich ebenfalls im ersten Post. Habe lediglich die deletes/NULL zuweisungen rausgenommen.



  • Hast du dir mal den Call-Stack angeschaut wenn die Exception kam um rauszubekommen wer genau die wirft?
    Wenn ein Socket geschlossen werden soll wird ja erstmal Lock aufgerufen. Es könnte ja sein, dass bei dir durch die Exception kein Unlock mehr aufgerufen wird und dadurch dein Problem entsteht. Du könntest ja mal versuchen alles in einem try/catch-block zu kapseln und im catch ein wenig aufräumen (unlock aufrufen).



  • 1. Du hast den Socket selbst erzeugt, damit wird die VCL das Zerstören nicht mehr selbst übernehmen.
    2. Beim Beenden des Programms zerstörst du den Socket nicht, der Socket bleibt also vorhanden, wird aber inaktiv, baut also die Verbindung ab. Hier könnte es sein, dass OnDisconnect erst dann aufgerufen wird, wenn deine Form bereits zerstört ist, was die Exception erklärt.

    ClientSocket->OnDisconnect=0;
    


  • Eigentlich sollte der Destruktor seiner Klasse das Zerstören des Sockets übernehmen.



  • Burkhi schrieb:

    1. Du hast den Socket selbst erzeugt, damit wird die VCL das Zerstören nicht mehr selbst übernehmen.
    2. Beim Beenden des Programms zerstörst du den Socket nicht, der Socket bleibt also vorhanden, wird aber inaktiv, baut also die Verbindung ab. Hier könnte es sein, dass OnDisconnect erst dann aufgerufen wird, wenn deine Form bereits zerstört ist, was die Exception erklärt.

    ClientSocket->OnDisconnect=0;
    

    Wird der Socket denn nicht zerstört wenn ich delete aufrufe?

    Also ich hab jetzt mal Socket->Unlock aufgerufen. Hab hier bei "SetActive" den Parameter ausgewertet, ist er false rufe ruf ich die Funktionen vom Socket in der Reihenfolge auf:
    ClientSocket->OnDisconnect = 0;
    ClientSocket->Disconnect(0); // sollte eigentlich keine Auswirkung haben wenn er nicht verbunden ist
    ClientSocket->Socket->Unlock(); // Lock() aufheben?
    ClientSocket->Socket->Close(); // damit der Socket geschlossen wird

    Im Destruktor der Klasse hab ich wieder das
    ClientSocket = NULL;
    delete ClientSocket;

    eingefügt. Bisher geht es immer noch nicht so wie es sollte.

    Hat eigentlich schon jemand mal den Code (siehe ersten Post) bei sich getestet um zu sehen ob die Exception bei euch auch kommt?



  • Maverick schrieb:

    ...
    ClientSocket = NULL;
    delete ClientSocket;

    Damit zerstörst du aber den ClientSocket nicht, weil du den Zeiger, der auf den Clientsocket zeigt, zuerst auf 0 setzt und dir damit den Zugriff auf das Objekt entziehst. Du musst das umgekehrt machen:

    delete ClientSocket;
    ClientSocket = NULL;
    


  • Burkhi schrieb:

    delete ClientSocket;
    ClientSocket = NULL;
    

    So kann das doch garnicht gehen. das object wird gelöscht, danach kann man ja nicht mehr darauf zugreifen,da würde man erst recht eine exception bzw. eine zugriffsverletzung bekommen.

    (mein monitor ist kaputt gegangen und muss über handy tippen)



  • Hast du meinen Post eigentlich gelesen?

    Maverick schrieb:

    Burkhi schrieb:

    delete ClientSocket;
    ClientSocket = NULL;
    

    So kann das doch garnicht gehen. das object wird gelöscht, danach kann man ja nicht mehr darauf zugreifen,da würde man erst recht eine exception bzw. eine zugriffsverletzung bekommen.

    ??
    ClientSocket = NULL; ist eine Zeigerzuweisung und kein Objektzugriff.
    -> Grundlagen!



  • audacia schrieb:

    ??
    ClientSocket = NULL; ist eine Zeigerzuweisung und kein Objektzugriff.
    -> Grundlagen!

    Evtl. möchtest du mein Post erneut lesen. Ich habe nicht darüber geschrieben das man auf das Objekt zugreift sondern das es (Objekt/Zeiger) gelöscht wird. Es spielt keine Rolle ob es ein Objektzugriff oder Zeigerzuweisung ist.

    Gelöscht ist gelöscht, alles andere danach erzeugt 'ne Zugriffsverletzung was auch logisch wenn das Objekt/Zeiger nicht mehr existiert...

    Was schliessen wir daraus? Wie üblich wird gleich "Grundlagen" gebrüllt und der Text vom eigentlichen Post ignoriert...

    Grundlagen.... etwas fehl plaziert... 👎



  • Maverick schrieb:

    Evtl. möchtest du mein Post erneut lesen.

    Sehr gerne. Ich muß eingestehen, daß mir beim ersten und auch beim zweiten Durchlesen weder deine Aussage noch deine anmaßende Empörung begreiflich geworden sind. Aber vielleicht hilft ein drittes Mal.

    Eingedenk der Möglichkeit, daß ich dich tatsächlich nur mißverstehe (ich hoffe es!), verkneife ich mir vorläufig, deiner Äußerung mit angemessener Arroganz zu begegnen. Jedoch wäre es nett, wenn du deine Aussage im Kontext der Grundlagen, so du sie beherrschst, ein wenig konkretisiertest.

    Maverick schrieb:

    Es spielt keine Rolle ob es ein Objektzugriff oder Zeigerzuweisung ist.

    Das heißt?

    Maverick schrieb:

    Gelöscht ist gelöscht, alles andere danach erzeugt 'ne Zugriffsverletzung was auch logisch wenn das Objekt/Zeiger nicht mehr existiert...

    Was willst du nun damit genau sagen?
    Daß

    obj = NULL;
    delete obj;
    

    die richtige, gar die einzig richtige und nicht AV-anfällige Methode zur Zerstörung eines Objektes ist?
    Oder doch etwas anderes?



  • Maverick schrieb:

    So kann das doch garnicht gehen. das object wird gelöscht, danach kann man ja nicht mehr darauf zugreifen,da würde man erst recht eine exception bzw. eine zugriffsverletzung bekommen.

    Hallo,

    da wird nix gelöscht, da wird nur der Speicher des Objektes freigegeben *mal einmisch*!

    delete Object; // Speicher freigeben
    Object = NULL; // Zeiger auf 0 setzen
    

    LG, Micha



  • audacia schrieb:

    Eingedenk der Möglichkeit, daß ich dich tatsächlich nur mißverstehe (ich hoffe es!), verkneife ich mir vorläufig, deiner Äußerung mit angemessener Arroganz zu begegnen.

    Angemessene Arroganz, da wärst du allerdings nicht der erste. Ich schätze deine üblichen Posts wirklich sehr und finde es immer wieder schön jemanden zu sehen der sich Zeit nimmt solche Posts zu verfassen, aber was haben solche Posts (siehe die letzten 2) letztendlich mit meinem Problem zu tun? Eigentlich nichts, oder?

    Fakt ist, dass der Socket aus irgend einem Grund nicht richtig zerstört wird bzw. bei der Zerstörung scheinbar (?) noch verbunden ist oder was auch immer.

    Socket Unlock etc. hat bisher auch nichts gebracht. Auch wenn ich mich wiederhole, die Exception kommt nur dann wenn ich den Socket verbinde, d.h. wenn ich meine "SetActive" Funktion aufrufe.

    Und die bisherigen Tests (siehe meine Posts) um die möglichen "fehlerhaften" Verbindungen zu trennen scheitern bisher.

    Leider hat es bisher scheinbar noch niemand für nötig gehalten den Code (siehe ersten Post) bei sich zu testen ob der Fehler auch bei anderen kommt. Ich hatte den Code extra auf ein minimum reduziert damit der Fehler reproduzierbar ist damit mir keiner nachsagen kann ich würde nach Code fragen. Ich habe mir eigentlich erhofft, dass jemand den Code bei sich testet und ggf. eine korrigierte Version postet, damit ich hätte sehen können WAS ich falsch gemacht bzw. vergessen habe.

    Bisher wurden keine konkreten Löschungsvorschläge gepostet sondern nur mutmassungen und die helfen nur bedingt weiter. Das Problem würde ich trotzdem gern gelöst haben da ich nach wie vor ratlos bin wie ich es beheben kann. Schlicht gesagt: Ich stecke fest.

    RandomAccess85 schrieb:

    Hallo,

    da wird nix gelöscht, da wird nur der Speicher des Objektes freigegeben *mal einmisch*!

    delete Object; // Speicher freigeben
    Object = NULL; // Zeiger auf 0 setzen
    

    LG, Micha

    Stimmt, da habe ich etwas verwürfelt, mein Fehler. Niemand ist perfekt.

    The delete operator destroys the object created with new by deallocating the memory associated with the object.



  • Maverick schrieb:

    aber was haben solche Posts (siehe die letzten 2) letztendlich mit meinem Problem zu tun? Eigentlich nichts, oder?

    In dem ersten dieser zwei Posts verwies ich nur auf meinen Post zu Anfang des Threads, wo ich dir schon erklärte, weshalb obj = NULL; delete obj; Unfug ist. Daß du es durchweg weiterverwendetest und auch rechtfertigen zu müssen meintest, ließ mich darauf schließen, daß du den Post nicht richtig gelesen oder verstanden hattest.

    audacia (ganz oben) schrieb:

    Du verwendest relativ häufig

    var = NULL;
    delete var;
    

    . Das ist eine interessante, doch leider recht ineffektive Variante des Freigebens von Objekten: die beiden Zeilen bewirken hinsichtlich der Destruktion und Deallokation nämlich gar nichts, und du hast ein Speicherleck. Zunächst setzt du den Zeiger auf 0 und versuchst sodann, einen Nullzeiger zu löschen - delete aber mit einem Nullzeiger aufzurufen, ist nur eine minder offensichtliche Variante von NOP.

    Maverick schrieb:

    Fakt ist, dass der Socket aus irgend einem Grund nicht richtig zerstört wird bzw. bei der Zerstörung scheinbar (?) noch verbunden ist oder was auch immer.

    Den Grund dafür hatte ich bereits in besagtem Post erläutert.

    Maverick schrieb:

    Leider hat es bisher scheinbar noch niemand für nötig gehalten den Code (siehe ersten Post) bei sich zu testen ob der Fehler auch bei anderen kommt.

    Was mich angeht, so mache ich mir die Mühe gewöhnlich erst dann, wenn naheliegende Vorschläge zur Lösung getestet und für unwirksam befunden wurden.

    In diesem Sinne: funktioniert es, wenn du die Objekte vernünftig freigibst? Falls nicht, teste ich es gerne mal.


Anmelden zum Antworten