std::use_facet<std::ctype<char>> crashes on linux

Hi,

Program

#include <locale>
int main(int argc, char* argv[]) {
    std::locale loc;
    std::use_facet<std::ctype<char>>(loc);
    return EXIT_SUCCESS;
}

Crashes with latest libc++ and libc++abi on Linux with backtrace

(gdb) bt
#0  0xb7fff424 in __kernel_vsyscall ()
#1  0x45abdbaf in raise () from /lib/libc.so.6
#2  0x45abf503 in abort () from /lib/libc.so.6
#3  0xb7fbf43c in abort_message (format=0xb7ff8264 "terminating with %s exception of type %s: %s") at ../src/abort_message.cpp:47
#4  0xb7fbf5f9 in default_terminate_handler () at ../src/cxa_default_handlers.cpp:63
#5  0xb7ff4f04 in std::__terminate (func=0xb7fbf4e0 <default_terminate_handler()>) at ../src/cxa_handlers.cpp:67
#6  0xb7ff44e5 in failed_throw (exception_header=<optimized out>) at ../src/cxa_exception.cpp:147
#7  __cxa_throw (thrown_object=0x804b058, tinfo=0xb7ffce50 <typeinfo for std::bad_cast>, dest=0xb7ff8170 <std::bad_cast::~bad_cast()>) at ../src/cxa_exception.cpp:242
#8  0xb7f14b82 in std::__1::locale::__imp::use_facet (
    this=0xb7fb91a0 <std::__1::locale::__imp& std::__1::(anonymous namespace)::make<std::__1::locale::__imp, unsigned int>(unsigned int)::buf>, id=28)
    at /home/vv/kom/libcxx/src/locale.cpp:432
#9  0xb7f15486 in std::__1::locale::use_facet (this=0xbfffeca0, x=...) at /home/vv/kom/libcxx/src/locale.cpp:574
#10 0x0804878e in main (argc=1, argv=0xbfffed54) at main.cpp:4

I have found that ‘std::ctype::id.__get()’ is 28 for me. I have constexpr enabled.

Thanks.

The only way I know to debug this is to monitor locale::id::__init() in locale.cpp. One needs to find out who is calling it, how often, from where, and what the current value of __next_id is, and what __id_ gets set to. I do not have a linux box to debug this with.

The design is that this gets called exactly 28 times with a default constructed locale and that id.__get() returns __id_-1:

long
locale::id::__get()
{
    call_once(__flag_, __fake_bind(&locale::id::__init, this));
    return __id_ - 1;
}

Furthermore locale::id::__init() is a private function of locale::id and is supposed to be only called within locale::id::__get().

One theory is: call_once isn't working.

Howard

Problems is static constructor of


locale::id ctype<char>::id;

is called after

Ok, I've seen this one before:

I have made mistake about libc++ being compiled with clang++. Issue became resolved after I used clang for libc++ compilation. Sorry for that.

No problem, thanks for the update.

Howard

A static member where the called constructor constructor is constexpr is
guaranteed to be constructed at compile-time by the C++11 standard. You
shouldn't need to apple constexpr to the variable itself.

-Eli