On 04/17/2013 08:43 AM, Stephan Bergmann wrote:
On 04/15/2013 03:34 PM, Michael Stahl wrote:
with commit f14f7a2e4568e3e85a0c8860beebd0376c5a8b51 MSVC builds will
link everything against the debug runtimes (MSVCRTD etc.), which enables
debug STL and other things.
[...]
since we have this enabled on other GCC platforms for years i'm not much
concerned about breakage on MacOSX; it would be helpful though if
somebody could try what happens when you run the "subsequentcheck" tests
which apparently isn't possible over SSH.
Another fallout is that, at least in
my Mac OS X 10.7.5, Xcode 4.6.1, --enable-dbgutil --with-macosx-sdk=10.7
master builds, writing numbers to std streams now suppresses all output
to those streams, so that e.g., SAL_WARN("foo","bar") only writes
"warn:foo:" to stderr (not even followed by a newline) and stops as soon
as it would write the numeric pid.
This is caused by basic_ostream::_M_insert
(/usr/include/c++/4.2.1/bits/ostream.tcc) catching an exception from
__check_facet(this->_M_num_put) and setting ios_base::badbit, which in
turn results from this->_M_num_put unexpectedly being null. Similar
problems on (non-debug) Linux had been addressed with long ago with
consistently exporting _ZGVNSt7num_put* and _ZNSt7num_put* symbols from
all libraries.
Why _GLIBCXX_DEBUG causes this problem on Mac OS X now, and how to solve
it, is still unclear to me.
For the record, here is what happens: At least on Mac OS X 10.7.5 with
Xcode 4.6.2 (with Command Line Tools installed), building the C++
program test.cc
#include <iostream>
#include <sstream>
int main() {
std::ostringstream s;
s << "a" << 1 << "b\n";
std::cout << s.str();
}
with
c++ -D_GLIBCXX_DEBUG test.cc
and running it (./a.out) prints only
a
(not followed by a newline) to stdout, not
a1b
(followed by a newline).
The reason is that in basic_ostream::_M_insert
(/usr/include/c++/4.2.1/bits/ostream.tcc) the
__check_facet(this->_M_num_put) call throws an exception, leading to
this->_M_setstate(ios_base::badbit).
This is because _M_num_put is null, because in
basic_ios::_M_cache_locale (/usr/include/c++/4.2.1/bits/basic_ios.tcc)
the call to has_facet<__num_put_type>(__loc) returns false.
This is because in has_facet
(/usr/include/c++/4.2.1/bits/locale_facets.tcc), the call to
_Facet::id._M_id() (with _Facet being __num_put_type aka
num_put<_CharT,ostreambuf_iterator<_CharT,_Traits>>, see
/usr/include/c++/4.2.1/bits/basic_ios.h) returns a fresh __i >=
__loc._M_impl->_M_facets_size.
This is because the static
template <typename _CharT, typename _OutIter>
locale::id num_put<_CharT, _OutIter>::id;
(/usr/include/c++/4.2.1/bits/locale_facets.h) is emitted into test.s as
.section __DATA,__datacoal_nt,coalesced
.globl __ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE ##
@_ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE
.weak_definition __ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE
.align 3
__ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE:
.space 8
so that a.out binds to this instance while libstdc++.6.dylib previously
has used a binding to its own instance (in calls via
std::ios_base::Init::Init -> ... ->
std::has_facet<std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char>>>>,
as can be observed in gdb).
Interestingly, while a.out contains its own weak definition of
__ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE, it
has __ZNSt5ctypeIcE2idE -- i.e.,
template<typename _CharT>
locale::id ctype<_CharT>::id;
(/usr/include/c++/4.2.1/bits/locale_facets.h) as an undefined reference
(so binds to the definition in libstdc++.6.dylib). Both are eventually
needed from _M_cache_locale; the two mainly differ in the number of
template parameters.
This all becomes irrelevant when compiling without -D_GLIBCXX_DEBUG, as
then (/usr/include/c++/4.2.1/bits/c++config.h)
_GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG is 0 so that
_GLIBCXX_EXTERN_TEMPLATE is 1, so that
extern template class basic_ostringstream<char>;
(/usr/include/c++/4.2.1/bits/sstream.tcc) becomes visible and the call
to
std::basic_ostringstream<char,std::char_traits<char>,std::allocator<char>>::basic_ostringstream(std::_Ios_Openmode)
(aka
__ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode)
in a.out calls directly into libstdc++.6.dylib, instead of carrying weak
definitions of all the code involved above in a.out.
(It makes no difference whether to build with c++, clang++, or g++. It
also makes no difference whether to also specify
-D_GLIBCXX_FULLY_DYNAMIC_STRING, which is known to be required in other
circumstances like
<http://lists.apple.com/archives/cocoa-dev/2009/Sep/msg01199.html> "Re:
getline 'free' problem." Also, results are the same at least with Xcode
4.6.1 and Xcode 4.6.2.)
Stephan
Context
- Re: [ANN] --enable-dbgutil: everyone gets a Debug STL! (continued)
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.