Functions in c++locale.o in libstdc++.a access the errno global int and this is
unsafe for use in threaded programs. Yet another object file in the same
library references the thread-local errno address function. Impact is minimal,
but indicates mixed compilation model object files are linked together into the
same library. This situation occurs on several platforms.

>From of "nm -g /opt/sfw/lib/libstdc++.a" on Solaris 10 (package SFWgcc34l
3.4.2):

  /opt/sfw/lib/libstdc++.a[basic_file.o]:
  [Index]   Value      Size    Type  Bind  Other Shndx   Name
  [38]    |         0|       0|NOTY |GLOB |0    |UNDEF  |___errno

  /opt/sfw/lib/libstdc++.a[c++locale.o]:
  [Index]   Value      Size    Type  Bind  Other Shndx   Name
  [27]    |         0|       0|NOTY |GLOB |0    |UNDEF  |errno

On this platform, both should be referencing ___errno.

The same problem appears to exist in libstdc++.so, but it's more difficult to
determine which object the reference comes from.

It's not clear to me how this problem happens at all, as both
basic_file_stdio.cc and c_locale.cc appear to be compiled with the same options
yet obviously were not.

Although the problem occurs on 3.4 libraries, the relevant files (c_locale.cc,
src/Makefile.am) have not to have changed much, so I suspect the problem is
still present.


Platforms I checked:
  Solaris 8 SPARC:  package SMCgcc342 3.4.2 by Steve Christensen
  Solaris 10 x86:   package SUNWgccruntime 11.10.0 by Sun
  Solaris 10 SPARC: package SFWgcc34l 3.4.2 by Sun
  HP-UX 11.11 PA RISC: package GNU_C_C++.GCC_3_4_5 by HP
  AIX 5.1:  (not sure where this one came from, I'm not an AIX wiz)
  Irix 6.5: (not sure where it came from)

  Linux RH 9: not a problem, no errno access
  Mac OS X:   not a problem, no errno access



Impact Analysis: what trouble can this errno access cause?

The functions in c_locale.cc which access errno are templates:

  __convert_to_v(const char*, float&, ...)
  __convert_to_v(const char*, double&, ...)
  __convert_to_v(const char*, long double&, ...)

These parse text and convert it to a floating point value. These in turn are
invoked from templates in locale_facets.tcc:

  num_get<_ChartT, _InIter>::do_get(..., float&)
  num_get<_ChartT, _InIter>::do_get(..., double&)
  num_get<_ChartT, _InIter>::do_get(..., long double&)
  money_get<_ChartT, _InIter>::do_get(..., long double&)

locale::facet is used in stream I/O.

Impact: Intermittent failures in multi-threaded applications when converting
floating point numbers from text to a binary value. More specifically, if the
text expresses an out-of-range value (e.g. exponent overflow for a 32-bit
float), an incorrect value may be returned rather than setting failbit.


-- 
           Summary: c++locale.o thread-unsafe in libstdc++
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: craig dot lawson at centrify dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31117

Reply via email to