Merkwürdiger Crash im VDR

  • Hallo,


    ich finde schon seit geraumer Zeit "merkwürdige" coredumps im VDR-Verzeichnis.
    Merkwürdig deshalb, weil ich mir keinen Reim drauf machen kann, was da passiert.


    Folgender Code (tools.c):


    Code
    void cListBase::Clear(void)
    {
      while (objects) {
            cListObject *object = objects->Next();
            delete objects;
            objects = object;
            }
      objects = lastObject = NULL;
      count = 0;
    }  // <--- Zeile 1457


    Der Backtrace dazu ist:


    Code
    #0  0x08100ba5 in cListBase::Clear (this=0x81e9044) at tools.c:1457
    #1  0x08100887 in ~cListBase (this=0xb74704c8) at tools.c:1372
    #2  0x080f301c in __tcf_0 () at status.c:14
    #3  0xb7d67562 in exit () from /lib/libc.so.6
    #4  0xb7d51568 in __libc_start_main () from /lib/libc.so.6
    #5  0x080887a1 in _start ()
    (gdb) print object
    $2 = (cListObject *) 0x0
    (gdb) print objects
    $3 = (cListObject *) 0x9ed5a58


    Ich verstehe nicht, was da crashen könnte?
    Das while() müsste Nullpointer-Zugriffe doch abfangen?

  • als jemand der net wirklich viel ahnung von der sache hat würde ich mal tippen, das da vllt. ein:

    Code
    while (objects->Next()) {
            cListObject *object = objects->Next();

    stehen müsste.


    ansonsten erhält man ja vllt. schon in der 2ten Zeile nen null-zeiger.
    wobei das auch net so wirklich sein kann, weil mit dem 'object' wird dann ja nix gemacht, also eigentlich auch kein crash.


    (vllt. sollte ich über pointer nicht referieren :P)

  • Weist du, mit welcher exception er ausgestiegen ist? wäre noch gut zu wissen.


    Die Zeilenangabe (1457) ist vermutlich falsch geraten. Dieser build ist doch sicher code-optimiert übersetzt, oder?
    Jedenfalls kann an dieser Code-Zeile objects nicht verschieden von NULL sein.


    Wenn ich raten müsste, würde ich sagen, die Dereferenzierung objects->Next() führt ins nirgendwo. cList ist da nicht wirklich zuverlässig geschrieben, man kann leicht die Listenstruktur durcheinander bringen. Wenn dann ein eigentlich schon freigegebenes Listenobjekt überschrieben wurde, knallts.


    Schwer zu sagen, wo da der Fehler ist, zumal noch nicht erkennbar ist, welche cList hier freigegeben wird. Wenn du es irgendwie provozieren kannst, versuch mal mit Valgrind dran zu gehen, da müsste dann die falsche Dereferenzierung erkannt werden.


    Gruß,


    Udo

  • Zitat

    Original von Thomas
    VDR standardmäßig mit "make" übersetzt.
    Wie könnte ich denn die Optimierung aussetzen?


    Zum Bleistift mit einer eigenen Make.config, und darüber mit der Definition von CXXFLAGS auf -O0 ...
    Die Datei in src Verzeichnis werfen, und den VDR normal mit make übersetzen.



    Ich hoffe ich erwähne hier Sachen, die nicht ehe schon bekannt sind,
    Andreas

  • [Weit aus dem Fenster raushängen]


    könnte man nicht einfach das ganze cListIrgendwas mit Containern aus der STL ersetzen?

    Aktuelle Systeme:
    VDR-Server: MSI KT6A Ultra FISR ; Athlon XP 2200+ ; GrKa Geforce 2 MX; 256MB DDR-SDRam Plugins: streamdev-server, remote
    2 x DVB-Budget Karte, Gentoo, Kernel 2.6.8 usw....

  • Zitat

    Originally posted by BlackKing
    könnte man nicht einfach das ganze cListIrgendwas mit Containern aus der STL ersetzen?


    Sicher könnte man. Da aber cList quer durch VDR und die meisten Plugins verwendet wird, wirst du ohne eine Emulation von cList deinen VDR wohl kaum noch übersetzt kriegen. Aber da Klaus ein bekennender STL-Hasser ist, wird uns das wohl so schnell nicht bevor stehen.


    (btw: mit 'nicht wirklich zuverlässig' meinte ich nicht, dass es fehlerhaft wäre. Man kann cList nur leicht falsch benutzen und so für herrliche Programmfehler sorgen. Und: Ja, ich spreche aus Erfahrung. ;) )


    Gruß,


    Udo

  • Der Code der Clear-Routine ist an sich in Ordnung. Probleme treten dann auf, wenn mehrere Threads die gleiche Liste simultan "bearbeiten". Der Code ist mit Sicherheit nicht thread-safe.


    Laut Backtrace sieht es so aus, als ob der Crash beim Stoppen des vdr auftritt (... exit() ...). Vielleicht werkelt da noch ein anderer Thread...


    CU
    Oliver

  • So, hab das jetzt mal wie angegeben umcompiliert.



    Der Code komplett:


    Code
    void cListBase::Clear(void)
    {
      while (objects) {
            cListObject *object = objects->Next();
            delete objects;
            objects = object;
            }
      objects = lastObject = NULL;
      count = 0;
    }


    objects ist nicht NULL, aber es knallt trotzdem? :rolleyes: :rolleyes:
    Die Zeile stimmt doch immer noch nicht...


    Der Segfault tritt übrigens tatsächlich beim Runterfahren auf, ich kann das beliebig provozieren.

  • Hmm, bei dem neuen Code steht doch:


    Code
    #0  0x081383c6 in cListBase::Clear (this=0x822d4c4) at tools.c:1452
    1452            delete objects;
    (gdb) bt
    #0  0x081383c6 in cListBase::Clear (this=0x822d4c4) at tools.c:1452

    d.h. der Fehler tritt beim delete auf. Also vermutlich doch ein delete auf ein bereits gelöschtes Objekt. Die Stelle bekommt man ohne Mutex eigentlich nicht threadsafe, aber mit einer gewissen Umkehrung der Reihenfolge wird die Wahrscheinlichkeit geringer. Was passiert denn bei:


    Code
    void cListBase::Clear(void)
    {
      while (objects) {
            cListObject *object = objects;
            objects = objects->Next();
            delete object;
            }
      objects = lastObject = NULL;
      count = 0;
    }


    Gruß,
    ARK

    VDR
    ASUS A7N8X-X, AMD 2600+, 2 GB, 320 GB HD, Hauppauge DVB-S 1.3, Hauppauge Nova-S-Plus, Funktastatur
    Debian 4.0/Etch-Kernel 2.6.18-5-486
    c't-VDR 6.1 mit e-tobi 1.6.0 (neu gepatched ohne sortrecordings), acpi, vdradmin-am, burn, osdteletext, ffnetdev, audiorecorder, infosatepg, ...
    Client
    dbox2 (Sagem 2xI_C) mit Neutrino-Derivat

  • Es wird wohl ein Verkettungsfehler in der Liste sein, wodurch ein ungültiger Zeiger an delete übergeben wird. So lange aber nicht mal klar ist, welche Liste hier freigegeben wird, ist der Fehler so nicht zu finden.


    Ich kann nur nochmal empfehlen, da mal mit Valgrind nachzuforschen. Valgrind dürfte den Zeiger auch noch nach dem Freigeben wieder erkennen, und kann ihn zuordnen.


    Gruß,


    Udo

  • Ich bin mir nicht so sicher ob ich mit valgrind effektiv umgehen kann.


    Hier ist mal die Ausgabe davon, wenn ich den VDR beende:



    Kann ich irgendwie mehr oder andere Info entlocken, die weiter hilft?

  • Zunächst mal findet er reichlich verdächtige Stellen und kleinere Fehler im Radio-Plugin und im DVD-Plugin. Das sieht mir aber alles eher nach übersehenen, aber unkritischen Fehlern aus.


    Dann kommt aber der "Thread 8" - für den es anscheinend keine Symbolinfos gibt. Warum, weiß ich auch nicht. Jedenfalls produziert dieser Thread einen segfault irgendwo tief drin.


    Um etwas mehr Übersicht zu gewinnen, solltest du so wenig Plugins wie möglich laden - natürlich nur, so lange das Problem bestehen bleibt. Und schau mal, ob du rausfinden kannst, was Thread 8 ist.


    Gruß,


    Udo

Jetzt mitmachen!

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