Compiler warning

  • Beim Übersetzen von VDR mit allen Patches (1-26) und folgendem Compiler

    Code
    1. gcc (SUSE Linux) 8.3.1 20190226 [gcc-8-branch revision 269204]
    2. Copyright (C) 2018 Free Software Foundation, Inc.
    3. This is free software; see the source for copying conditions. There is NO
    4. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


    erhalte ich folgende Warnung:


    VDR compiliert durch und läuft auch soweit. Gelegentlich gibt es aber beim umschalten von Kanälen und gleichzeitigen laufenden Aufnahmen Speicherzugriffsfehler

    folgender Art:

    Code
    1. Mär 24 22:45:56 vnas2 kernel: traps: general protection fault ip:7fd745e3fea6 sp:7fd6b17f9a70 error:0 in libc-2.29.so[7fd745ddc000+14c000]

    Können diese Warnungen etwas mit den general Protection fault zu tun haben?

    Wenn nicht, ist es möglich diese Warnungen in Hinblick auf 2.4.1 zu fixen?


    Beste Grüße





  • recording.c:604


    Code
    1. char buf[4];
    2. sprintf(buf, "#%02X", (unsigned char)*p);
    3. memmove(p + 2, p, strlen(p) + 1);
    4. strncpy(p, buf, 3);
    5. p += 2;


    in buf wird ein c string aus einer Raute '#', zwei Zeichen der hex-Zahl sowie eine nachfolgende Null abgelegt;

    strncpy kopiert drei bytes maximal, da passt die Null nicht mehr rein. Der compiler warnt hier zu Recht, dass kein nulltermierter c-String in p stehen wird.

    auch das Increment von p sieht um ein byte oder zwei byte zu klein aus - ansonsten hätte man nicht vorher "#%02X" nutzen sollen.

  • ..möglicherweise war ursprünglich gemeint


    char buf[4];

    sprintf(buf, "#%02X", (unsigned char)*p);

    memmove(p + 2, p, strlen(p) + 1);

    strncpy(p, buf, 4);

    p += 3;

  • Danke für die schnelle Analyse.

    hab mal einen Patch gebaut.

  • Die erste Warnung des compilers in ci.c:1577 hat auch so seine Berechtigung.

    'Text' kann länger als 256 Zeichen sein und struct answer könnte je nach compiler aligned sein,

    u.U. auch strlen(answer.text) != strlen(Text) in SendData.



  • Hier rächt es sich in gewissem Maß, dass der VDR eine "Mischung" aus C++ und C ist.

    Klar, der Compiler macht in gewissem Maß ein Audit und findet solche Fehler, aber mein Informatik-Dozent hat nicht nur einmal betont, dass man in C++ immer die stdlib nutzen soll und das C-Strings böse sind. Mit C++-Strings wäre das nicht passiert :P

  • Zur 3. Warnung:

    Ich glaube es sollte genügen die Zeile 607 in recording.c inmemcpy(p, buf, 3); zu ändern.

    Hier wird ein Zeichen durch einen 3 Byte Hexcode ersetzt - deshalb zuerst die Verschiebung des String um 2 Bytes nach hinten um Platz zu schaffen. Das '0'-Byte des Ersatzstring darf nicht mitkopiert werden, ein strncpy(p, buf, 4); wie im Patch schneidet den String gleich nach der ersten Ersetzung ab.

    Helmut

  • Der Vorschlag in #11 eliminiert ebenfalls die Compiler Warnung.

    Im folgenden, ein Patch hierzu:

  • RHS : Wenn du in ci.c, Zeile 1584 strncpy ebenfalls durch memcpy sollte diese Warnung auch nicht mehr auftauchen. Hier soll kein "C"-String in den Buffer geschrieben werden.


    Die beiden strncpy() Aufrufe sind keine Fehler, memcpy(IndexTs, &IndexPes, sizeof(*IndexTs));in recording.c, Zeile 2637 allerdings schon;

    Die Länge von struct tIndexPes (64 Bit) ist kleiner als die der struct tIndexTs es soll aber nur der Inhalt von IndexPes in die ersten 64 Bit von IndexTS kopiert werden. Also müsste hier memcpy(IndexTs, &IndexPes, sizeof(*IndexPes)); stehen.

    Das kann - oder besser - wird die Ursache für den Speicherzugriffsfehler sein.


    Helmut


    Edit: ich sehe gerade das die Funktion ConvertToPes mit obigen Fehler eben nur bei Pes-Aufnahmen verwendet wird - das sind Aufnahmen mit der Endung ".vdr" ->

    bool IsPesRecording = fileName && endswith(fileName, ".vdr");

    Da das bei die eher nicht der Fall sein wird (oder?), kann der Speicherzufriffsfehler aber auch eine andere Ursache haben

  • Danke


    hier ein Patch zum Fix ci.c:


    Meine Aufnahmen sind .ts files.

    Beim compilieren erhalte ich mit o.g. Fix für recording.c zeile 2637 folgende Fehlermeldung:


    Code
    1. CC recording.o
    2. g++ -g -O3 -Wall -march=native -Woverloaded-virtual -Wno-parentheses -fPIC -c -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DREMOTE_KBD -DLIRC_DEVICE=\"/var/run/lirc/lircd\" -DVIDEODIR=\"/srv/vdr/video\" -DCONFDIR=\"/var/lib/vdr\" -DARGSDIR=\"/etc/vdr/conf.d\" -DCACHEDIR=\"/var/cache/vdr\" -DRESDIR=\"/usr/local/share/vdr\" -DPLUGINDIR=\"/usr/local/lib/vdr\" -DLOCDIR=\"/usr/local/share/locale\" -I/usr/include/uuid -I/usr/include/freetype2 -o recording.o recording.c
    3. recording.c: In member function 'void cIndexFile::ConvertToPes(tIndexTs*, int)':
    4. recording.c:2637:43: error: no match for 'operator*' (operand type is 'tIndexPes')
    5. memcpy(IndexTs, &IndexPes, sizeof(*IndexPes));
    6. ^~~~~~~~~
  • Hab ich übersehen - IndexPes ist ja kein Pointer sondern die struct selbst, also nun ohne "*" -> memcpy(IndexTs, &IndexPes, sizeof(IndexPes));.


    Helmut


    Kleine Ergänzung: damit soll eigentlich nur der Fehler behoben werden, die Warnung wird vermutlich bleiben.

    Ich kann es jetzt nicht ausprobieren, aber vieleicht braucht es dafür noch &IndexTS->offsetals erstes Argument.

  • Ohne Stern gibt es keinen Error sondern folgende Warnung:

    Code
    1. g++ -g -O3 -Wall -march=native -Woverloaded-virtual -Wno-parentheses -fPIC -c -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DREMOTE_KBD -DLIRC_DEVICE=\"/var/run/lirc/lircd\" -DVIDEODIR=\"/srv/vdr/video\" -DCONFDIR=\"/var/lib/vdr\" -DARGSDIR=\"/etc/vdr/conf.d\" -DCACHEDIR=\"/var/cache/vdr\" -DRESDIR=\"/usr/local/share/vdr\" -DPLUGINDIR=\"/usr/local/lib/vdr\" -DLOCDIR=\"/usr/local/share/locale\" -I/usr/include/uuid -I/usr/include/freetype2 -o recording.o recording.c
    2. recording.c: In member function 'void cIndexFile::ConvertToPes(tIndexTs*, int)':
    3. recording.c:2637:45: warning: 'void* memcpy(void*, const void*, size_t)' copying an object of non-trivial type 'struct tIndexTs' from an array of 'struct tIndexPes' [-Wclass-memaccess]
    4. memcpy(IndexTs, &IndexPes, sizeof(IndexPes));
    5. ^
    6. recording.c:2502:8: note: 'struct tIndexTs' declared here
    7. struct tIndexTs {
    8. ^~~~~~~~
    9. CC thread.o
  • Das mit der Warnung habe ich erwartet.

    In der Eränzung von meinem letzten Post hätte ich mir die Zeile so vorgstellt: memcpy(&IndexTs->offset, &IndexPes, sizeof(IndexPes)); - vielleicht lässt es gcc dann als "trivial" durchgehen obwohl es nach dem Datentype eigentlich mmer noch nicht richtig passt.

    Ich werde es am Abend ausprobieren.


    Helmut

  • Bei &IndexTs->offsetgibt es einen Fehler wegen dem Pointer ein bit-field.

    Aber so bemängelt gcc-8.2.0 in recording.c nichts mehr:

    Helmut

  • Könntet ihr eventuell einen Patch mit allen nötigen Änderungen posten?

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)