Problem mit meinem serled-plugin

  • Hallo,


    beim Schneiden von Aufnamen kommt es bei mir immer wieder zu Abstürzen (reproduzierbar mit der Selben aufname). Die letzten Worte von vdr sind:


    *** glibc detected *** double free or corruption: 0x4161e398 ***
    *** glibc detected *** double free or corruption: 0x4161d510 ***
    *** glibc detected *** double free or corruption: 0x4161eee8 ***
    *** glibc detected *** double free or corruption: 0x4161e1b8 ***
    *** glibc detected *** double free or corruption: 0x4161e3e0 ***


    An sich bin ich da selber schuld, weil das nur auftritt, wenn ich mein serled-Plugin aktiviere. Und auch dann nur wenn ich eine LED Blinken lasse, wenn eine Schneidevorgang läuft. Mein Verdacht fällt auf die beiden Threads die ich erzeuge. Einer überprüft ob vdr schneidet, ein anderer lässt die LED bliniken. Ich benutze auch nicht die VDR-thread-Klasse, sondern rufe selbst pthread_create auf.


    Testweise hab ich noch die Zeilen mit "pthread_detach" und "pthread_setschedparam" nach meinem pthread_create aufruf eingefügt, so wie es in der thread Klasse vom vdr auch gemacht ist. Das ändert aber leider nichts.


    Das Problem trat erst nach dem Wechsel von vdr-1.2.6 nach vdr-1.3.44/5 auf.


    Hat jemand eine Idee, woran das liegen könnte. An sonsten versuche ich mal die VDR-thread-Klassen zu verwenden.


    Viele Grüße


    Euer frausch

  • Ein klassisches Problem der reinen C-Programmierung. Wenn du für eine Aufgabe eine Klasse hast, nimm einfach diese. Sie mag nicht hundertprozentig deinen Bedürfnissen entsprechen, dafür gibt es aber die Vererbung.


    Zurück zu deinem Problem.


    Du verwendest Speicher und dieser wird an einer Stelle wieder freigegeben. Dummerweise ruft jemand entweder die Methode nochmal auf oder aber macht das vollkommen eigenständig mit der gleichen Variable. Dann wird Speicher freigegeben, der bereits nicht mehr dem Programm gehört. Korrekterweise wird das Programm dann beendet werden.


    Um dieses Problem einzukreisen, hilft nur eins: Grundregeln der Programmerierung einhalten. Dazu zählt auch, das nach dem Freigeben von Speicher die referenzierende Variable zurückgesetzt wird. Wenn man "new/delete" verwendet, war es das mit den Grundregeln, da ein "delete" auf einen 0-Pointer still ignoriert wird. Was "malloc/free" dann macht weiß ich nicht...


    Natürlich ist es wichtig, Pointer auch zu initialisiieren. Am besten bei der Erzeugung des Objektes. Ansonsten läuft man Gefahr, Speicher freizugeben, der niemals allokiert wurde. Auf die Aussage, "der Compiler macht das schon" mag ich mich nicht verlassen:


    Code
    Object::Object()
    : m_pSimplePointer(0)
    ...
  • Am Besten nimmt man garkeine Zeiger, sondern Instanzen und Referenzen ;) (wenn ein Objekt sowieso während der gesamten Programmlaufzeit existiert, wieso dynamisch erzeugen? Wenn ein Objekt by-reference übergeben wird, warum dann Zeiger?)... Also am Besten zuerst schauen ob Du das Problem nicht schon durch Designanpassungen erschlagen kannst.


    Und im Zweifel nimmst Du Smartpointer :D

  • LordJaxom, da hast du recht.


    Dafür darfst du jetzt die Smartpointer im plain VDR Projekt zählen und dann die zeichenkettenverarbeitenden Klassen den blanken "char*" gegenüberstellen. Anschließend darfst du auch noch die Plugins hinzunehmen...


    Die meisten Sachen sind halt in der Freizeit von Leuten gemacht worden, die ansonsten nichts mit Programmierung zu tun haben.


    Insofern bleibt es ein Wunschtraum.

  • Ja ich könnte und würde und lasse es dann doch lieber ;)


    Nein, im Ernst - Klaus weiss denke ich dass er programmieren kann, ich vermute mal er kommt aus einem C-Lager und ist erst später mit C++ vertraut geworden, und da findet sich so ein Stil sehr oft.


    Gerade was die Leute angeht, die nur in ihrer Freizeit programmieren, kann ich jedoch nur immer wieder raten (wenn ich gefragt werde ;D) Referenzen, Streams, Container und Strings zu benutzen, weil sie das Potenzial haben von vornherein viele Fehler zu vermeiden die Klaus nicht macht, ein Neuling aber schon...

  • Hallo,


    danke für eure Hilfe. Meine Programmierkenntnisse wurzeln noch in viel finstereren Abgründen als LordJaxom annimmt (BASIC auf ZX-Spectrum dann über einen kurzen abstecher in Pascal und c schließlich C++).


    Auf den ersten Blick hab ich jetzt nichts gesehen, wo ich zu dem Zeitpunkt irgend ein Object mit delete lösche. Während das Plugin läuft wird tatsächlich kein Object erzeugt oder vernichtet.


    Ich bin übrigens mit stl-Vectoren und thread auch shon mal auf die Nase gefallen. Bsp: Ein thread fürt eine Methode eines Objects aus, das in einem vecrtor gespeichert ist. Ein weiterer thread fügt dem vector elemente mit push_back hinzu. Das hat mich ungefähr zwei Wochen gekostet. Deshalb fülle ich lieber Pointer in stl-vectoren wenn ich mit Threads arbeite.


    Ich denke ich werde wohl am Wochenende da mal genauer reinschauen müssen.


    Viele Grüße


    Euer frausch

  • Zitat

    Original von frausch
    Auf den ersten Blick hab ich jetzt nichts gesehen, wo ich zu dem Zeitpunkt irgend ein Object mit delete lösche. Während das Plugin läuft wird tatsächlich kein Object erzeugt oder vernichtet.


    Bist du dir sicher? Irgendwo kommt diese Meldung ja her.


    Zitat

    Original von frausch
    Ich bin übrigens mit stl-Vectoren und thread auch shon mal auf die Nase gefallen. Bsp: Ein thread fürt eine Methode eines Objects aus, das in einem vecrtor gespeichert ist. Ein weiterer thread fügt dem vector elemente mit push_back hinzu. Das hat mich ungefähr zwei Wochen gekostet. Deshalb fülle ich lieber Pointer in stl-vectoren wenn ich mit Threads arbeite.


    Das liegt wohl am mangelhaften Durchlesen der Dokumentation. Die STL ist nicht threadsafe. Wenn die Möglichkeit besteht, das verschiedene Threads parallel damit arbeiten, muß der Zugriff auf STL- Objekte synchronisiert werden. Dafür gibt es normalerweise eine Mutex-Klasse und ein Helferlein zum Benutzen des Mutex.


    Dierk

  • Hallo,


    möglicherweise hab ich das Problem gefunden. Es ligt wohl an der cCutter :: Active() funktion, die nicht Thread-Sicher ist. Mein Plugin ruft diese Funktion jede secunde auf um zu sehen ob gerade Geschnitten wird. Ich hab diese Funktion mal mit einem Mutex abgesichert, und es scheint zu gehen (soweit man das bei der Beseitigung von Race-Conditions sagen kann). Ich hab hier mal einen Patch angehängt. Nachdem dies die Funktion des VDR ansonsten nicht verändert, oder beeinträchtigt würde ich Vorschlagen dies in zukünftige versionen von VDR einzubauen.


    Viele Grüße


    Euer frausch

  • Zitat

    Ich bin übrigens mit stl-Vectoren und thread auch shon mal auf die Nase gefallen. Bsp: Ein thread fürt eine Methode eines Objects aus, das in einem vecrtor gespeichert ist. Ein weiterer thread fügt dem vector elemente mit push_back hinzu. Das hat mich ungefähr zwei Wochen gekostet. Deshalb fülle ich lieber Pointer in stl-vectoren wenn ich mit Threads arbeite.


    Leute, Pointer in Vectoren, auf die verschiedene Threads zugreifen???
    Da muss man sich nicht wundern, wenn man ewig nach Fehlern suchen muss. Ich finde es wirklich super, wenn sich Leute in ihrer Freizeit mit Software befassen, aber macht es euch nicht selbst unnötig schwer.


    Ansonsten: weiter so.


    Zitat

    Auf die Aussage, "der Compiler macht das schon" mag ich mich nicht verlassen


    Das sollte man auch nicht, denn der Compiler wird keinen Speicher freigeben?! Oder hat das irgendwer angenommen?


    Viele Grüße
    KdF

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!