Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is valgrind reporting errors for libstdc++'s std::locale?

Related question: wifstream with imbue, locale produces valgrind errors

I am using cppreference's (potentially flawed) examples, in particular the one present on their imbue page. Using the command line on the coliru online compiler:

clang++ -std=c++14 -stdlib=libstdc++ -O3 -Wall -Wextra -pedantic-errors 
        -pthread main.cpp && valgrind ./a.out

the following test cases produce errors like these (unless I state "no errors"):

==5421== Invalid read of size 8
==5421==    at 0x590CBC0: wcscmp (wcscmp.S:208)
==5421==    by 0x4EAC174: std::moneypunct<wchar_t, false>::~moneypunct() (monetary_members.cc:927)
==5421==    by 0x4EAC1D8: std::moneypunct<wchar_t, false>::~moneypunct() (monetary_members.cc:932)
==5421==    by 0x4EA1695: std::locale::_Impl::~_Impl() (locale_classes.h:412)
==5421==    by 0x4EA17D8: std::locale::~locale() (locale_classes.h:521)
==5421==    by 0x400955: main (in /tmp/1412433400.2497/a.out)
==5421==  Address 0x5c2e0b8 is 0 bytes after a block of size 8 alloc'd
==5421==    at 0x4C2AC27: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5421==    by 0x4EABE61: std::moneypunct<wchar_t, false>::_M_initialize_moneypunct(__locale_struct*, char const*) (monetary_members.cc:847)
==5421==    by 0x4EA3CD7: std::locale::_Impl::_Impl(char const*, unsigned long) (locale_facets_nonio.h:993)
==5421==    by 0x4EA406A: std::locale::locale(char const*) (localename.cc:42)
==5421==    by 0x40094D: main (in /tmp/1412433400.2497/a.out)

cppreference's imbue example:

#include <iostream>
#include <sstream>
#include <locale>

int main()
{
    std::istringstream iss;
    iss.imbue(std::locale("en_US.UTF8"));

    std::cout << "Current locale: " << iss.getloc().name() << '\n';

    iss.imbue(std::locale());
    std::cout << "Global locale : " << iss.getloc().name() << '\n';
}

libstdc++ - errors

libc++ - no errors

The linked questioned at the top's reduced example:

#include <iostream>
#include <locale>

int main (int argc, char **argv) {
    try {
        std::locale * l1 = new std::locale("de_DE.UTF-8");
        delete l1;

        std::locale l2("de_DE.UTF-8");

    } catch(...) {
        return 0;
    }
    return 0;
};

libstdc++ - errors

libc++ - no errors

Linked bug report in above question's reduced example:

#include <wchar.h>

void foo(int)
{
}

int main()
{
    wchar_t *a=new wchar_t[2], *b=new wchar_t[2];
    size_t j;

    a[0]=b[0]='A';
    a[1]=b[1]=0;

    foo(wcscmp(a, b));
    delete[] a;
    delete[] b;

    return 0;
}

libstdc++ - no errors

libc++ - no errors

I've added the bug report's test case for completeness even though they produce no errors. Coliru's valgrind version is 3.7.0, and OP in the linked thread mentions upgrading to 3.8.1 and still receiving errors. I'm not on a Linux machine at the moment, and so cannot test it myself. If it makes any difference, here's glibc output:

GNU C Library (Ubuntu EGLIBC 2.15-0ubuntu10.7) stable release version 2.15, by Roland McGrath et al.
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.6.3.
Compiled on a Linux 3.2.60 system on 2014-08-28.
Available extensions:
    crypt add-on version 2.1 by Michael Glad and others
    GNU Libidn by Simon Josefsson
    Native POSIX Threads Library by Ulrich Drepper et al
    BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

Where does the bug lie? cppreference's examples, valgrind, or libstdc++?


1 Answers

It's a false positive in Valgrind, fixed here.

like image 109
Employed Russian Avatar answered Jun 14 '26 03:06

Employed Russian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!