Compile Warnings in vnsiserver

  • > So wie es ausschaut steckt der Fehler in vdr, nicht im Plugin.

    in welcher der 9 neuen neuen Zeilen?

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Weiß ich nicht, evtl poppt auch ein älterer Fehler in vdr auf.


    Aber schau auf die Reihenfolge der letzten calls im backtrace, nicht im Plugin, sondern in VDR.

    Code
    #5  0x00007ffff769c7c7 in malloc_printerr (str=str@entry=0x7ffff77b39f8 "malloc(): unaligned tcache chunk detected") at mall#6  0x00007ffff76a108c in tcache_get_n (ep=<optimized out>, tc_idx=<optimized out>) at malloc.c:3176
    #7  tcache_get (tc_idx=<optimized out>) at malloc.c:3192
    #8  __GI___libc_malloc (bytes=bytes@entry=10) at malloc.c:3313
    #9  0x00007ffff7683648 in __vasprintf_internal
    #10 0x000000000055ccab in cString::sprintf (fmt=fmt@entry=0x56d138 "%s (%s)") at tools.c:1178
    #11 0x0000000000492b08 in cChannel::Name (this=this@entry=0x6fb1b0) at /usr/src/packages/BUILD/vdr-git-2.6.3/tools.h:189
    #12 0x00007ffff7865e5f in cVNSIClient::processCHANNELS_GetChannels (this=0x7fffcc00a060, req=...) at vnsiclient.c:1181
  • Code
    unaligned tcache chunk detected

    Das bedeutet, dass VORHER ein Fehler passiert ist, der hier sichtbar wird.

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Muss ja auch nicht an dem Patch liegen. Beim Durchlesen der Änderungen ist mir nur das free() ins Auge gesprungen. Dazu kam das zwei Plugins wegen der Änderung nicht mehr kompilieren wollten (was nicht an der Änderung sondern an den verwendeten Compiler-Parametern gelegen hat). Vielleicht ein Zufall, vielleicht bringt es irgendwen auf eine Idee. Und wenn nicht, dann halt Pech gehabt.

  • Kann es sein, dass da ein

    Code
    if (this == &String)
        return *this;

    oder vergleichbares fehlt?


    Nicht, dass ich das wirklich beurteilen könnte, ich bin nur beim rekapitulieren zufällig über den Hinweis gestolpert.

    Und die anderen Operatoren haben das auch drin.

    Gruss
    SHF


  • Kann es sein, dass da ein

    Code
    if (this == &String)
        return *this;

    oder vergleichbares fehlt?


    Nicht, dass ich das wirklich beurteilen könnte, ich bin nur beim rekapitulieren zufällig über den Hinweis gestolpert.

    Und die anderen Operatoren haben das auch drin.

    Baut das doch mal ein, und testet. Ich hätte jetzt nicht erwartet, dass jemand

    a = a;

    schreibt, aber man weiß ja nie ...

    Könnte schon sein, dass es das ist.


    ~ Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Hier ist diese Absicherung auch drin: https://www.geeksforgeeks.org/…nment-operator-in-cpp-11/


    Vielleicht gibt es auch irgendwelche "Sonderfälle" bei denen so eine Zuweisung stattfindet ohne das man so direkt "a = a" schreibt. Finde ich eh etwas bedenklich wie viel man über die interne Funktionsweise von C++ bescheid wissen muss um mit der Sprache keine Unfälle zu bauen.


    Wenn man in diesen Edge-Case rennt, dann gibt man auf jeden Fall den internen Pointer frei. Ich hätte dann aber eher einen Crash wegen Zero-Pointer-Dereference erwartet.

  • Hier ist diese Absicherung auch drin: https://www.geeksforgeeks.org/…nment-operator-in-cpp-11/

    Danke, das ist der eine Artikel, in dem ich es gesehen hatte.

    Ich dachte, es war bei cppreference.com gewesen, da es dann natürlich nicht wieder finden...


    Ich bin beim Suchen dann immer nur auf den Folgenden gestoßen :versteck :

    learn.microsoft.com: Bewegungskonstruktoren und Bewegungszuweisungsoperatoren (C++)

    Da wird sogar zwei mal explizit davor gewarnt.



    Wann diese Selbstzuweisungen auftreten, würde mich auch mal interessieren.

    Unter Umständen ist es aber gar nicht so selten.

    Selbst was triviales wie a = a+x; könnte bei x == 0 ja theoretisch irgendwie dazu werden.

    Gruss
    SHF


  • Ich mal den Patch #48 auf vdr-2.6.6 original angewandt, es crashed wie zuvor. Mit dem revert des Commit lt. #37

    gibt es keinen crash.


    Vielleicht ist folgende Beobachtung noch interessant:


    Wenn nur 1 vnsi-client am vnsiserver connected ist crashed vdr selten

    bei 2 vnsi-clienten erfolgt der crash häufig

    bei 3 vnsi-cllenten efolgt der crash fast immer.


    Die crashes gibt es beim umschalten eines Programms in den vnsi-clienten.

  • Ich werde dann wohl die Tage für Arch erstmal einen Patch einbauen der den Move-Operator wieder rausnimmt. Wenn ich damit wieder volle Plugin-Kompatibilität erhalte, ist es mir das erstmal wert. Ich will in Kürze für einen guten Freund einen neuen VDR-Server aufbauen und bei denen läuft praktisch alles mit (vielen) LibreElec-Clients. Stabile VNSI-Unterstützung ist da also absolute Voraussetzung.


    Soll keine Kritik an der Änderung an sich sein. Egal wie viele Beispiele ich lese, mit dem letzten Vorschlag von SHF ist die Implementierung praktisch "wie aus dem Fachbuch". Aber ob das eine Race-Condition oder gar ein GCC-Bug ist, kann wohl auf die Schnelle auch keiner rausfinden. Bei Sprachen wie C++ ist man halt schnell auch an einem Punkt wo man Fehler im Assembly-Code suchen muss. Linus hat das wohl ein paarmal veranstaltet und den GCC-Entwicklern dann genau sagen können wo sie Bockmist gebaut haben.

  • Vielleicht nochmal ein unqualifizierter Einwurf aber nehmen wir an der Move Operator hat einen Einfluss (was ja wahrscheinlich ist). Kann man den mit wenig Aufwand so patchen das man geloggt bekommt in welcher Situation (Kontext) er aufgerufen wird?

  • Das gemeine daran ist, dass der dazu passende constructor genauso unvorhergesehen Effekte erzeugen kann.

    Siehe das neue C++ keyword explizit.

  • Vielleicht nochmal ein unqualifizierter Einwurf aber nehmen wir an der Move Operator hat einen Einfluss (was ja wahrscheinlich ist). Kann man den mit wenig Aufwand so patchen das man geloggt bekommt in welcher Situation (Kontext) er aufgerufen wird?

    Versuch doch mal:

    Code
    cString &cString::operator=(cString &&String)                                                                                                   
    {                                                                                                                                               
      if (this == &String)                                                                                                                          
         return *this;                                                                                                                              
      esyslog("cString move, old string \"%s\", new string \"%s\"", s?s:"NULL", String.s?String.s:"NULL");
      free(s);                                                                                                                                      
      s = String.s;                                                                                                                                 
      String.s = NULL;                                                                                                                              
      return *this;                                                                                                                                 
    }


    Möglicherweise reicht das ja

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Ich habe das mal so eingebaut, leider passiert kein Crash mehr. Nur der Syslog wird mit den Meldungen vollgeschüttet.


    was mich wundert sind solche Meldungen:

    Ich betreibe den vdr headless, es sind keine DVB Karten verbaut.


    Ansonsten eine überwältigende Menge an Nachrichten des EPG Threads:




    Es scheint durchaus eine Race Situation zu geben, da diese Flut von Meldungen das Timing so verändern, das der Chrash nicht auftritt.

  • Also folgendermaßen?


    Code
    cString &cString::operator=(cString &&String)                                                                                                   
    {                                                                                                                                               
      if (this == &String)
        esyslog("cString move, old string \"%s\", new string \"%s\"", s?s:"NULL", String.s?String.s:"NULL");
        return *this;                                                                                                                              
      free(s);                                                                                                                                      
      s = String.s;                                                                                                                                 
      String.s = NULL;                                                                                                                              
      return *this;                                                                                                                                 
    }

Jetzt mitmachen!

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