[
https://issues.apache.org/jira/browse/STDCXX-1056?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13201653#comment-13201653
]
Stefan Teleman edited comment on STDCXX-1056 at 2/6/12 10:02 PM:
-----------------------------------------------------------------
I understand the need for writing small and efficient methods, but I don't
agree that the problem reported in STDCXX-839 relates to the test running for
too long. The fact that the test program doesn't terminate or abends with
SIGHUP is a symptom of undefined run-time behavior.
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/stdcxx-4.2.1/build/tests][02/06/2012
16:49:50][1512]>> /usr/bin/time -p ./22.locale.numpunct.mt --nthreads=4
--nloops=100 >& t.out
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/stdcxx-4.2.1/build/tests][02/06/2012
16:50:13][1513]>> tail -17 t.out
# INFO (S1) (4 lines):
# TEXT: creating a thread pool with 4 threads
# CLAUSE: lib.locale.numpunct
# LINE: 548
# +-----------------------+----------+----------+----------+
# | DIAGNOSTIC | ACTIVE | TOTAL | INACTIVE |
# +-----------------------+----------+----------+----------+
# | (S1) INFO | 11 | 11 | 0% |
# | (S2) NOTE | 1 | 1 | 0% |
# | (S8) ERROR | 0 | 3 | 100% |
# | (S9) FATAL | 0 | 1 | 100% |
# +-----------------------+----------+----------+----------+
real 4.95
user 1.07
sys 0.22
{noformat}
This test case (and the corresponding 22.locale.moneypunct.mt) consistently
exhibit run-time crashes or insane behavior (CPU being pinned at 99% forever)
without the serialization fix.
The interesting part is where this race condition actually happens: it's in
include/loc/_num_put.cc:
{code title=_num_put.cc|borderStyle=solid}
template <class _CharT, class _OutputIter /* = ostreambuf_iterator<_CharT> */>
_TYPENAME num_put<_CharT, _OutputIter>::iter_type
num_put<_CharT, _OutputIter>::
_C_put (iter_type __it, ios_base &__flags, char_type __fill, int __type,
const void *__pval) const
{
const numpunct<char_type> &__np =
_RWSTD_USE_FACET (numpunct<char_type>, __flags.getloc ());
char __buf [_RWSTD_DBL_MAX_10_EXP];
// will grow as necessary and may need to be deleted
char *__pbuf = __buf;
const string __grouping = __np.grouping (); // <----- !!
const char* const __grp = __grouping.c_str (); // <----- !!
const _RWSTD_STREAMSIZE __prec = __flags.precision ();
{code}
was (Author: steleman):
I understand the need for writing small and efficient methods, but I don't
agree that the problem reported in STDCXX-839 relates to the test running for
too long. The fact that the test program doesn't terminate or abends with
SIGHUP is a symptom of undefined run-time behavior.
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/stdcxx-4.2.1/build/tests][02/06/2012
16:49:50][1512]>> /usr/bin/time -p ./22.locale.numpunct.mt --nthreads=4
--nloops=100 >& t.out
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/stdcxx-4.2.1/build/tests][02/06/2012
16:50:13][1513]>> tail -17 t.out
# INFO (S1) (4 lines):
# TEXT: creating a thread pool with 4 threads
# CLAUSE: lib.locale.numpunct
# LINE: 548
# +-----------------------+----------+----------+----------+
# | DIAGNOSTIC | ACTIVE | TOTAL | INACTIVE |
# +-----------------------+----------+----------+----------+
# | (S1) INFO | 11 | 11 | 0% |
# | (S2) NOTE | 1 | 1 | 0% |
# | (S8) ERROR | 0 | 3 | 100% |
# | (S9) FATAL | 0 | 1 | 100% |
# +-----------------------+----------+----------+----------+
real 4.95
user 1.07
sys 0.22
{noformat}
This test case (and the corresponding 22.locale.moneypunct.mt) consistently
exhibit run-time crashes or insane behavior (CPU being pinned at 99% forever)
without the serialization fix.
The interesting part is where this race condition actually happens: it's in
include/loc/_num_put.cc:
{code title=_num_put.cc|borderStyle=solid}
template <class _CharT, class _OutputIter /* = ostreambuf_iterator<_CharT> */>
_TYPENAME num_put<_CharT, _OutputIter>::iter_type
num_put<_CharT, _OutputIter>::
_C_put (iter_type __it, ios_base &__flags, char_type __fill, int __type,
const void *__pval) const
{
const numpunct<char_type> &__np =
_RWSTD_USE_FACET (numpunct<char_type>, __flags.getloc ());
char __buf [_RWSTD_DBL_MAX_10_EXP];
// will grow as necessary and may need to be deleted
char *__pbuf = __buf;
const string __grouping = __np.grouping (); // <----- !!
const char* const __grp = __grouping.c_str (); // <----- !!
const _RWSTD_STREAMSIZE __prec = __flags.precision ();
// [ ... ]
{code}
> std::moneypunct and std::numpunct implementations are not thread-safe
> ---------------------------------------------------------------------
>
> Key: STDCXX-1056
> URL: https://issues.apache.org/jira/browse/STDCXX-1056
> Project: C++ Standard Library
> Issue Type: Bug
> Components: 22. Localization
> Affects Versions: 4.2.1, 4.2.x, 4.3.x, 5.0.0
> Environment: Solaris 10 and 11, RedHat and OpenSuSE Linux, Sun C++
> Compilers 12.1, 12.2, 12.3
> Issue is independent of platform and/or compiler.
> Reporter: Stefan Teleman
> Labels: thread-safety
> Fix For: 4.2.x, 4.3.x, 5.0.0
>
> Attachments: stdcxx-1056.patch
>
>
> several member functions in std::moneypunct<> and std::numpunct<> return
> a std::string by value (as required by the Standard). The implication of
> return-by-value
> being that the caller "owns" the returned object.
> In the stdcxx implementation, the std::basic_string copy constructor uses a
> shared
> underlying buffer implementation. This shared buffer creates the first
> problem for
> these classes: although the std::string object returned by value *appears* to
> be owned
> by the caller, it is, in fact, not.
> In a mult-threaded environment, this underlying shared buffer can be
> subsequently modified by a different thread than the one who made the initial
> call. Furthermore, two or more different threads can access the same shared
> buffer at the same time, and modify it, resulting in undefined run-time
> behavior.
> The cure for this defect has two parts:
> 1. the member functions in question must truly return a copy by avoiding a
> call to the copy constructor, and using a constructor which creates a deep
> copy of the std::string.
> 2. access to these member functions must be serialized, in order to guarantee
> atomicity
> of the creation of the std::string being returned by value.
> Patch for 4.2.1 to follow.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira