C++, valgrind, únik paměti, stderr vs. stdout

Sekcia: Programovanie 12.05.2018 | 18:17
Avatar xkucf03   Používateľ

Mám program v C++ a v main() odchatávám svoje výjimky. V catch bloku chci jen vypsat chybu a ukončit program.

Narazil jsem na zvlášní chování – pokud hlášku vypisuji na standardní výstup, nehlásí mi Valgrind žádné chyby: All heap blocks were freed -- no leaks are possible. Pokud ale chci chybu vypsat na chybový výstup, hlásí mi: still reachable: 5,120 bytes in 2 blocks

Jasně, program stejně končí, tak je to vlastně jedno, ale stejně bych na to rád přišel. Jediné, co měním, je cíl výstupu. Zde jsou příklady z catch bloku a příslušné hlášky z Valgrindu:

// wcout << e.getMessge().c_str() << endl; // valgrind: All heap blocks were freed -- no leaks are possible
// wcerr << e.getMessge().c_str() << endl; // valgrind: still reachable: 5,120 bytes in 2 blocks
fwprintf(stderr, L"Caught exception: %s\n", e.getMessge().c_str()); // valgrind: still reachable: 5,120 bytes in 2 blocks
// fwprintf(stdout, L"Caught exception: %s\n", e.getMessge().c_str()); // valgrind: All heap blocks were freed -- no leaks are possible
// wprintf(         L"Caught exception: %s\n", e.getMessge().c_str()); // valgrind: All heap blocks were freed -- no leaks are possible

Chtěl bych tam mít tu odkomentovanou variantu, abych nezasíral standardní výstup chybovými hláškami.

P.S. Následně jsem zjistil, že to ani nesouvisí s výjimkami. Pokud kdekoli v programu zapíši něco na chybový výstup, Valgrind hlásí: still reachable…

Nakonec jsem to vyřešil pomocí fclose(stderr). Je tedy potřeba vždy chybový výstup explicitně zavírat, zatímco standardní výstup ne?

    • RE: C++, valgrind, únik paměti, stderr vs. stdout 12.05.2018 | 20:20
      Avatar bedňa LegacyIce-antiX  Administrátor

      Ja do toho moc nevidím, ale vyzerá na bug v glibc, alebo nejakej inej knižnici.

      Aké prepínače si použil na Valgrind?

      Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org
      • RE: C++, valgrind, únik paměti, stderr vs. stdout 12.05.2018 | 23:40
        Avatar xkucf03   Používateľ

        Bez přepínačů, základní nastavení.

        Zkoušel jsem napsat minimální program, kde bude jen ten fwprintf() a tam se mi to nepodařilo nasimulovat.

        V tom mém programu chyba zmizí, když přepíšu fwprintf(stderr, L"…\n") na fwprintf(stdout, L"…\n") nebo přidám fclose(stderr). S výjimkami to nakonec nesouvisí a s těmito konkrétními funkcemi taky ne, protože stejný rozdíl byl i mezi wcout a wcerr.

        Zkusím si s tím ještě pohrát a kdych na něco přišel, tak dám vědět.

    • RE: C++, valgrind, únik paměti, stderr vs. stdout 12.05.2018 | 20:24
      Avatar borg Fedora  Administrátor

      asi to bude tym ze cerr je nebufferovany a cout pouziva buffer. Pre detailnejsi rozbor chyby by bolo dobre vidno aspon kus kodu. vyhnut memory leakom sa mozes pouzivanim smart pointrov. Inak valgrind obcas hlasi aj false positive memory leaky.

      • RE: C++, valgrind, únik paměti, stderr vs. stdout 12.05.2018 | 23:43
        Avatar xkucf03   Používateľ

        Ad „cerr je nebufferovany a cout pouziva buffer“

        Na to už jsem taky přišel, když jsem na to koukal přes strace :-)

        Jinak ukazatele tam ani nepoužívám…

        • RE: C++, valgrind, únik paměti, stderr vs. stdout 13.05.2018 | 00:17
          Avatar bedňa LegacyIce-antiX  Administrátor
          Ad „cerr je nebufferovany a cout pouziva buffer“

          Už toto by stálo za nahlásenie bugu, pretože to bug je, keď sa výstup chová nepredvídateľne.

          Asi by trebalo sa pozrieť do dokumentácie Valgrind a skúsiť nejaké agresívnejšie prepínače pre viac výstupu, na začiatok napr:

          --leak-check=full --show-reachable=yes

          Táto správa neobsahuje vírus, pretože nepoužívam MS Windows. http://kernelultras.org
          • RE: C++, valgrind, únik paměti, stderr vs. stdout 13.05.2018 | 07:21
            Avatar WlaSaTy   Návštevník
            Už toto by stálo za nahlásenie bugu, pretože to bug je, keď sa výstup chová nepredvídateľne.

            Ten výstup sa chová predvídateľne. Funkcia cout je naviazaná na cin, a spláchne sa pri čítaní. Funkcia cerr má nastavený príznak unitbuf, a preto sa spláchne pri každom dovolaní operátora << .

            Bug je, ak to nevieš a tak máš predstavu založenú na fantázii a nie faktoch.

          • RE: C++, valgrind, únik paměti, stderr vs. stdout 13.05.2018 | 09:23
            Avatar Miroslav Bendík Gentoo  Administrátor

            cerr je unbuffered aby boli chybové hlášky zobrazené aj napriek tomu, že program na nasledujúcom riadku havaroval. S bufferom by sa hláška mohla stratiť.

          • RE: C++, valgrind, únik paměti, stderr vs. stdout 13.05.2018 | 11:38
            Avatar borg Fedora  Administrátor

            Nie je to bug.