What does this std::ostream related stack trace mean?
-
12-06-2021 - |
Question
I'm trying to build a C++ library for an integrated/mobile platform. The platform has a decent set of libs, including stdc++. The library I'm trying to build uses ofstream and whenever it attempts to use a class that depends on ofstream, I get a 'bad_cast' exception.
0 0xb082d9b1 in SignalKill ()
from /home/preet/bbndk-2.0.1/target/qnx6/x86/lib/libc.so.3
1 0xb081aa7e in raise ()
from /home/preet/bbndk-2.0.1/target/qnx6/x86/lib/libc.so.3
2 0xb0818cb8 in abort ()
from /home/preet/bbndk-2.0.1/target/qnx6/x86/lib/libc.so.3
3 0xb87c48bf in __gnu_cxx::__verbose_terminate_handler ()
at ../../../../../libstdc++-v3/libsupc++/vterminate.cc:93
4 0xb87c23d6 in __cxxabiv1::__terminate (
handler=0xb87c47c0 <__gnu_cxx::__verbose_terminate_handler()>)
at ../../../../../libstdc++-v3/libsupc++/eh_terminate.cc:38
5 0xb87c2421 in std::terminate ()
at ../../../../../libstdc++-v3/libsupc++/eh_terminate.cc:48
6 0xb87c2563 in __cxxabiv1::__cxa_throw (obj=0x859e710, tinfo=0xb87f4c24,
dest=0xb87c0670 <std::bad_cast::~bad_cast()>)
at ../../../../../libstdc++-v3/libsupc++/eh_throw.cc:83
7 0xb875e88c in std::__throw_bad_cast ()
at ../../../../../libstdc++-v3/src/functexcept.cc:52
8 0xb8798c0d in __check_facet<std::ctype<char> > (__f=<optimized out>)
at /home/builder/hudson/650-gcc-4.4/svn/linux-x86-o-ntox86/i486-pc-nto-qnx6.5.0/pic/libstdc++-v3/include/bits/basic_ios.h:49
9 widen (__c=<optimized out>, this=<optimized out>)
at /home/builder/hudson/650-gcc-4.4/svn/linux-x86-o-ntox86/i486-pc-nto-qnx6.5.0/pic/libstdc++-v3/include/bits/basic_ios.h:440
10 std::endl<char, std::char_traits<char> > (__os=...)
at /home/builder/hudson/650-gcc-4.4/svn/linux-x86-o-ntox86/i486-pc-nto-qnx6.5.0/pic/libstdc++-v3/include/ostream:539
11 0xb8793c2d in std::ostream::operator<< (this=0x84db220,
__pf=0x804f64c <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@plt>)
at /home/builder/hudson/650-gcc-4.4/svn/linux-x86-o-ntox86/i486-pc-nto-qnx6.5.0/pic/libstdc++-v3/include/ostream:113
12 0x0805240d in QDecViewport::QDecViewport (this=0x86da6c0, parent=0x0)
at ../qml_osg_viewport/qdecviewport.cpp:12
13 0x08051cca in QDeclarativePrivate::QDeclarativeElement<QDecViewport>::QDeclarativeElement (this=0x86da6c0)
at /usr/local/Trolltech/QtLighthouse-4.8.2-i386/include/QtDeclarative/qdeclarativeprivate.h:83
14 0x08051d3c in QDeclarativePrivate::createInto<QDecViewport> (
memory=0x86da6c0)
at /usr/local/Trolltech/QtLighthouse-4.8.2-i386/include/QtDeclarative/qdeclarativeprivate.h:91
15 0xb8ad5ec5 in ?? ()
16 0x086da6c0 in ?? ()
17 0x00000000 in ?? ()
Frames 7-11 are relevant and the ones I need help understanding. The line of code frame 12 is referring to is just:
OSG_INFO << "Hello OSG" << std::endl;
Where OSG_INFO is a stream redirector used for logging. I'm able to use std::cout in the same way without any issue. Unmangling frame 11 gives me:
__pf=0x804f64c <std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)@plt>)
Which is still pretty cryptic... and I'd understand things going crazy if maybe I was trying to pass something really strange to the ofstream output operator, but its just text. Does anyone have any suggestions?
Solution
std::endl
has the following behavior, citing C++11 §27.7.3.8/1:
Calls
os.put(os.widen('\n'))
, thenos.flush()
.
Frame 9 says that endl
's call to widen
is failing, i.e. that OSG_INFO.widen('\n')
is failing. widen
, in turn, has the following behavior (§27.5.5.3/12):
Returns:
use_facet< ctype<char_type> >(getloc()).widen(c)
use_facet
itself will throw bad_cast
if the facet is not present in the imbued locale (§22.3.2/3), but your stack trace doesn't indicate that this is the case. (Then again, I haven't dug through the libstdc++ internals to verify that it's doing things by the book...)
I assume that __check_facet
is called before use_facet
(or use_facet
was inlined and disappeared from the stack trace), with the same net effect; this implies that OSG_INFO
has been imbued with some locale that does not have the std::ctype<char>
facet present – bad times!
Alternatively, it may have been imbued with some locale with a facet present that simply doesn't handle widen('\n')
gracefully. But there's no way to know for sure, and nothing else we can tell you, without knowing what OSG_INFO
is and/or how it's implemented.