Multithreading New/Delete



  • Das ist die Fehlermeldung: memory clobbered past end of allocated block

    Bedeutet das, dass ich meine Speicherbereiche überschreibe?
    Habe alle memmove-aufrufe mit 1000 if's gesichert... also längen geprüft. die sollten eig nichts überschreiben.



  • matti83 schrieb:

    Habe alle memmove-aufrufe mit 1000 if's gesichert... also längen geprüft.

    Dazu verwendet man normalerweise nicht if , sondern assert . Einerseits erfährst du so direkt von dem Fehler, andererseits verbrätst du im Release-Modus keine Rechenzeit mit der Überprüfung von Logikfehlern.

    Zu Low-Level-Funktionalität und ihrer Fehleranfälligkeit habe ich im Weiteren schon was gesagt. Wo genau brauchst du std::memmove() ?

    Ansonsten halt die übliche Taktik anwenden: Nach und nach Teile weglassen/auskommentieren, bis du den Fehler eingrenzen kannst.



  • matti83 schrieb:

    Das ist die Fehlermeldung: memory clobbered past end of allocated block

    Bedeutet das, dass ich meine Speicherbereiche überschreibe?

    Ja



  • Meldung von gdb auf ein print eines Objekts:

    warning: can't find linker symbol for virtual table for ByteBuffer' value warning: foundconstruction vtable for BaseObj-in-ByteBuffer' instead

    ByteBuffer ist von BaseObj abgeleitet.
    Die Meldung weißt auch darauf hin, dass ich meinen Speicher irgendwo zerschieße - ja?

    Wenn ich mir den Speicher zerschieße - wie kann es dann sein, dass das Prog einwandfrei läuft, wenn ich delete vollständig weg lasse? Zufall?



  • matti83 schrieb:

    Wenn ich mir den Speicher zerschieße - wie kann es dann sein, dass das Prog einwandfrei läuft, wenn ich delete vollständig weg lasse? Zufall?

    Wenn du das delet weglässt, hast du ein Speicherleck, das heißt, der Speicher wird einfach nicht mehr freigegeben. Dein Programm läuft dann problemlos durch, allerdings musst du hoffen, dass das Betriebssystem hinterher den verlorenen Speicher wieder freigibt.



  • Naja, es läuft auch nur so lange problemlos durch, wie noch genügend Speicher zur Verfügung steht (inkl. swap). Wenn das Programm mal Tage/Wochen läuft kann auch das in die Hose gehen.



  • Die Frage ist ja eigentlich auch: "Warum schmiert es weg, wenn das delete benutzt wird?"



  • matti83 schrieb:

    Die Frage ist ja eigentlich auch: "Warum schmiert es weg, wenn das delete benutzt wird?"

    Vermutlich weil du nach dem delete auf den Speicher zugreifst, den du freigegeben hast. Ein Debugger sollte dir das sagen können.

    Das ganze memmove/delete-Gedöns hört sich so oder so sehr unsicher an. Vielleicht solltest du es nach RAII-Manier wegkapseln, damit du nicht mehr mit der Hand in die Zahnräder greifen musst 😉



  • Ist alles nach RAII-Manier programmiert



  • memory clobbered past end of allocated block                                             
    
    Program received signal SIGABRT, Aborted.
    
    #9  0x0805d7aa in ~GByteBuffer (this=0x8191b20, __in_chrg=<value optimized out>,         
        __vtt_parm=<value optimized out>) at GByteBuffer.cpp:69                              
    69            }                                                                          
    Current language:  auto
    The current source language is "auto; currently c++".
    (gdb) l
    64                if( mBuffer ){
    65                  delete mBuffer;
    66                  mBuffer = 0;
    67                }
    69            }
    

    er schmiert irgendwie am ende des destructors weg 😕 Zeile 69



  • Jetzt wäre der relevante Code der Klasse hilfreich. Wobei relevant heißt, dass du den Inhalt der Klasse möglichst kürzt und checkst, ob mit dem Rest der Fehler immernoch auftritt. Hast du unit-Tests für die Klasse geschrieben?



  • Moin,

    also so wie das aussieht ist die socket-programmierung daran schuld.

    ich habe das ganze jetzt mal auf einen thread reduziert und der fehler trat trotzdem auf. das prog hat folgenden ablauf:

    1: accept connection
    2: read data
    3: write data
    4: close socket
    5: goto 1

    mein read data hatte jetzt ein programmierfehler, so dass es einmal zu viel den read auf den socket gemacht hat und quasi an dieser stelle hing.

    dadurch, dass google-chrome direkt eine zweite anfrage gesendet hat ist das programm dann weg geschmiert.

    das sollte doch aber eig garnicht passieren, solange ich nicht wieder zu 'accept connection' komme, müsste der browser doch blockiert sein.
    sind die sockets nicht sauber getrennt? vllt sollte ich mir nochmal nen socket-tut durchlesen.



  • Vielleicht sendet Chrome die 2. Anfrage ja, bevor er eine Antwort auf die 1. bekommen hat?
    Bin grad nicht 100% sicher ob das bei HTTP OK ist, aber vorstellen könnte ich es mir.
    Ansonsten hilft da, wie meistens, den coolen Onkel Debugger zu fragen.



  • Alles klar. Abgehakt. Double-Delete gefunden. Vielen Dank für die vielen Anregungen.



  • Nur aus Neugier: wie hast du's denn jetzt gefunden?



  • Hab es leider doch noch nicht gefunden.

    Dachte erst das die Stelle den DoubleDelete macht.
    Macht aber nur ein einfachen Delete. Als ich es raus genommen habe, ging alles.
    Nur leider war der Speicher iwann voll... weil es eben kein DoubleDelete war.

    Es muss mein ByteBuffer sein. Wenn ich direkt vom Socket lese geht auch alles. Wenn ich den ByteBuffer dazwischen schalte schmiert er nach gefühlten 500 runs ab.
    Werd noch verrückt :p



  • Ahhh... wohl auch nicht der ByteBuffer.
    Der Fehler muss iwo zwischen New und Delete liegen.

    1: create some objects
    2: maybe throw an exception
    3: delete the objects
    4: goto 1

    single-threaded läuft es... multi-threaded schmiert er weg: 'memory clobbered past end of allocated block'

    die exception wird durch ein 'broken pipe' (Socket) verursacht

    das müsste bedeuten, dass ein thread eine ausnahme erzeugt, die einen anderen thread beim erzeugen eines Objektes stört! Ist das möglich? Ich kann es mir nicht vorstellen. 😕



  • Einfach Threads vermeiden. Mit den Dingern holt man sich nur Probleme ins Haus. Ich hasse Multithread Programmierung! 😡



  • Guter Tipp 🙄



  • matti83 schrieb:

    das müsste bedeuten, dass ein thread eine ausnahme erzeugt, die einen anderen thread beim erzeugen eines Objektes stört! Ist das möglich? Ich kann es mir nicht vorstellen. 😕

    Wenn eine Ausnahme in Thread A ein Problem in Thread B bewirkt, kann das folgende Ursachen haben:

    - Durch das Stackunwinding in Thread A werden Dinge freigegeben/zerstört, die in thread B benutzt werden.
    - Ein Objekt in Thread A ist nicht threadsafe und hinterlässt einen undefinierten/inkonsistenten Zustand in einer geteilten Ressource.
    - Thread B benutzt fälschlicherweise Objekte aus Thread A, die nicht für einen gemeinsamen Gebraucht konzipiert sind.
    - Thread B benutzt eine geteilte Ressource nicht korrekt/nicht in threadsicherer Manier, d.h. fragt z.B. Fehlerzustände nicht ab, die in Thread A durch die Exception gesetzt wurden.


Anmelden zum Antworten