[Bug libstdc++/31117] New: c++locale.o thread-unsafe in libstdc++

2007-03-09 Thread craig dot lawson at centrify dot com
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  SizeType  Bind  Other Shndx   Name
  [38]| 0|   0|NOTY |GLOB |0|UNDEF  |___errno

  /opt/sfw/lib/libstdc++.a[c++locale.o]:
  [Index]   Value  SizeType  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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-09 Thread craig dot lawson at centrify dot com


--- Comment #2 from craig dot lawson at centrify dot com  2007-03-10 00:15 
---
Seems like that define should come from gcc's "-pthread" option so it applies
to all source files.


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-12 Thread craig dot lawson at centrify dot com


--- Comment #4 from craig dot lawson at centrify dot com  2007-03-12 18:26 
---
Perhaps there are different degrees of thread safety here.

If I write my multi-threaded program such that only one thread does stream I/O
with libstdc++, I would expect it to operate safely with respect to the locale
issue. But it will not: any other thread which modifies errno (via set_errno)
is potential trouble for my stream I/O thread.

On the other hand, if __convert_to_v was compiled to use the errno address
function, my program would be correct.


-- 


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



[Bug c/31153] New: -Wconversion does not catch return value mismatch

2007-03-12 Thread craig dot lawson at centrify dot com
In functions declared to return unsigned int, -Wconversion correctly warns when
a constant signed int is returned. But -Wconversion fails to warn when the
return value is an identifier with type signed int.

Seen in gcc 3.2.3 (Red Hat) and 4.0.1 (Mac OS X)


-- 
   Summary: -Wconversion does not catch return value mismatch
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
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=31153



[Bug c/31153] -Wconversion does not catch return value mismatch

2007-03-12 Thread craig dot lawson at centrify dot com


--- Comment #1 from craig dot lawson at centrify dot com  2007-03-12 18:53 
---
Test program (Create a New Attachment is not working for me today):

const int  i = -1;

unsigned int slip_one_by()
{
return i;
}

unsigned int caught_me()
{
return -1;
}

$ gcc -c unsigned_return.c -Wconversion
unsigned_return.c: In function `caught_me':
unsigned_return.c:10: warning: negative integer implicitly converted to
unsigned type

Expected a warning for line 5, too.


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-12 Thread craig dot lawson at centrify dot com


--- Comment #6 from craig dot lawson at centrify dot com  2007-03-12 19:23 
---
> Anyway, what happens in the GNU systems is that errno is a per-thread variable
> and the __convert_to_v code has to do nothing special, just safely use it.

I agree. The problem is that this is not happening. __convert_to_v is not
safely using the per-thread errno. Instead, it is using the global errno.

The cause is not the __convert_to_v code but something in an include file or a
gcc option which causes the code to be compiled incorrectly. Yet another file
in the same library compiled with the same gcc options does access the
thread-safe errno correctly. That a discrepancy exists indicates a problem
somewhere.

The intent of this bug is to call attention to this misuse of errno and the
indication of an underlying problem.


Thank you for explaining the issues with setlocale. Worse than I thought.


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-12 Thread craig dot lawson at centrify dot com


--- Comment #8 from craig dot lawson at centrify dot com  2007-03-12 20:07 
---
Not on Linux: correct.

I could give it a try, but I haven't built this library before. If you could
point me to a brief how-to, I could give it a try on a Solaris 10 SPARC.

Rather than code around it, I would first review the preprocessor output from
the two files which access errno. If the compiler options are the same, then
problem is somewhere in a header file. And if that's the case, it would be
useful to understand the issue.


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-14 Thread craig dot lawson at centrify dot com


--- Comment #10 from craig dot lawson at centrify dot com  2007-03-14 18:13 
---
Found it.

The problem is that the library is not be ing properly compiled for
multi-threaded use, but that by some luck basic_file.cc happened to be compiled
that way anyway. c++locale.cc was not so lucky.

There are two possible solutions.

The solution I believe is best is to compile with the -pthread option. This is
what GNU's own documentation recommends for building MT-compatible objects, and
is designed to be supported across all platforms. This option defines the
appropriate CPP symbol which causes the errno function to be declared rather
than the errno global int. I'm not sure where to insert this flag in configure.
If you can tell me, I can try it out.

The next best solution is to add 

  #include 
  #include 

to the top of  before it includes . These files define the
same CPP symbol as -pthread. However, I'm not confident that  will do
the job on all platforms. Someone who knows better should evaluate this.


-- 


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



[Bug c++/31177] New: make install fails on Solaris 10 SPARC

2007-03-14 Thread craig dot lawson at centrify dot com
make install fails with:

  echo 'SYSTEM_HEADER_DIR="'"`echo /usr/include | sed -e :a -e
"s,[^/]*/\.\.\/,," -e ta`"'"' \
>
/test/gcc412/test/gcc-4.1.2/usr/local/lib/gcc/sparc-sun-solaris2.10/4.1.2/install-tools/mkheaders.conf
/bin/sh: : cannot execute
/bin/sh: /]*/../,, -e ta: not found
sed: command garbled: s,[


The problem is in install-mkheaders target. Expansion of SYSTEM_HEADER_DIR
within double quotes results in mismatched quotes. Shell then tries to evaluate
the sed pattern.

Fix:
File:
  BUILD-ROOT/host-sparc-sun-solaris2.10/gcc/Makefile
  (This Makefile was generated. Not sure from where.)
Change:
SYSTEM_HEADER_DIR = `echo $(NATIVE_SYSTEM_HEADER_DIR) | sed -e :a -e
"s,[^/]*/\.\.\/,," -e ta`
to:
SYSTEM_HEADER_DIR = `echo $(NATIVE_SYSTEM_HEADER_DIR) | sed -e :a -e
's,[^/]*/\.\.\/,,' -e ta`

(double quotes to single quotes)


-- 
   Summary: make install fails on Solaris 10 SPARC
   Product: gcc
   Version: 4.1.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
    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=31177



[Bug target/31177] make install fails on Solaris 10 SPARC

2007-03-14 Thread craig dot lawson at centrify dot com


--- Comment #3 from craig dot lawson at centrify dot com  2007-03-14 20:00 
---
Yeah... I missed that one.

I have bash installed. If bash works, why can't the configure script find it
automatically?


-- 

craig dot lawson at centrify dot com changed:

   What|Removed |Added

 Status|RESOLVED|VERIFIED


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



[Bug target/31177] make install fails on Solaris 10 SPARC

2007-03-14 Thread craig dot lawson at centrify dot com


--- Comment #4 from craig dot lawson at centrify dot com  2007-03-14 20:01 
---
Yeah... I missed that one.

I have bash installed. If bash works, why can't the configure script find it
automatically?


-- 


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



[Bug target/31177] make install fails on Solaris 10 SPARC

2007-03-14 Thread craig dot lawson at centrify dot com


--- Comment #5 from craig dot lawson at centrify dot com  2007-03-14 20:01 
---
(oops. hit "verified" by mistake.)


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-14 Thread craig dot lawson at centrify dot com


--- Comment #13 from craig dot lawson at centrify dot com  2007-03-15 02:02 
---
(reply to comment #11)

Shear luck: Fair enough. I don't claim to understand it all, either, especially
how it came to be this way.

What appears to be happening on Solaris 10 is that  followed
by "/usr/include/locale.h" defines the CPP symbols which select the errno
function. That happens in the wrong order in c++locale.cc. In that file, moving
 to the end of the list fixes the problem, too. In fact, moving it
below  is all that is necessary. And so I thought,  and 
are configuring the compilation environment for threads and they don't have
much to be concerned about ... why isn't  doing that -- that's what
needs it the most!

And what is the down side of  including files which may select the
errno function? The errno function is always safe, even in single-threaded
programs. I'm not aware that there's any more to it than this, though I could
be wrong.

-pthread vs -pthreads: In the 3.x releases which I use, this is the case. It's
-pthread on every system except for Solaris where it's -pthreads. Also except
on Irix where gcc doesn't recognize the option at all. But 4.1.2 gcc on Solaris
(which I just built) accepts either one interchangably. That's progress. Not
sure about 4.1.2 Irix. And there are plenty of other platforms that I don't
know about.

Testing: After several full builds, I began experimenting with the includes and
narrowed my test down to this command taken from my build log:

  BUILD-ROOT/host-sparc-sun-solaris2.10/gcc/xgcc  -c c++locale.cc -E |
grep __errno

If it displays "extern int *___errno();", then the build will produce a
multi-threaded object. If not, single-threaded as it does now.


(reply to comment #12)

Sane set of headers: Yes, I agree with you. Should not be happening. Perhaps
it's better to focus on  rather than -pthread.

Exactly which CPP symbol: On this platform, to select the errno function,
/usr/include/errno.h requires

  defined(_REENTRANT) || defined(_TS_ERRNO) || _POSIX_C_SOURCE - 0 >=
199506L

My guess is most likely _REENTRANT or _POSIX_C_SOURCE.  ->
/usr/include/locale.h -> /usr/include/sys/feature_tests.h,
/usr/include/sys/ccompile.h, /usr/include/sys/isa_defs.h,  Some of these
system header files do testing and setting of _REENTRANT and _POSIX_C_SOURCE,
but they're difficult to follow. One frustration I have with CPP output is that
#defines are not visible. I can see comments (with -CC), but that's not quite
good enough. That's as deep as I've dug at this point.


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-15 Thread craig dot lawson at centrify dot com


--- Comment #16 from craig dot lawson at centrify dot com  2007-03-15 18:15 
---
(In reply to comment #15)

Tried it. Did not work.


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-15 Thread craig dot lawson at centrify dot com


--- Comment #18 from craig dot lawson at centrify dot com  2007-03-15 18:39 
---
(In reply to comment #17)
> Why? 

Don't know. The file and change were included as expected.

Without fully understanding how CPP is evaluating these files, we're shooting
in the dark. gcc's -E and -CC options provide only a limited view: they show
everything except the "#" statements evaluated. Is there a way to see exactly
what CPP has evaluated? Either an environment variable, an option, or another
tool?


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-15 Thread craig dot lawson at centrify dot com


--- Comment #21 from craig dot lawson at centrify dot com  2007-03-15 19:07 
---
(In reply to comment #17)
> Why? 

OK, now I know why. Reason is that os_defines.h is included after errno.h.

Here's the include sequence:

  c++locale.cc

  /usr/include/errno.h<-- extern int errno

  
<-- _TS_ERRNO -- too late

I also now know why basic_file.cc gets the errno function:
/usr/include/sys/feature_tests.h defines _POSIX_C_SOURCE to 199506L, and that's
what errno.h needs. When compiling c++locale.cc, _POSIX_C_SOURCE is also set to
the same value, but it happens after errno.h is processed.

Thanks Andrew for -dD. That's a good one.


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-15 Thread craig dot lawson at centrify dot com


--- Comment #23 from craig dot lawson at centrify dot com  2007-03-15 19:26 
---
(In reply to comment #22)

> Oh yes, you are totally right. The problem is that  is one of the very
> few c headers not including  first. We can easily fix that.

Why did  not include ? Was this intentional?


> Ok, but on other targets I don't think we can trust locale.h to always include
> something similar and enable the thread safe errno.

I agree. They're all going to be different. But the evidence from basic_file.o
indicates that they all do something.


> Thus, my preference goes for the plan of adding that define in os_defines.h (+
> adjusting  of course). Are you positive about figuring out something
> similar to _TS_ERRNO for the other targets?

Instead of _TS_ERRNO and equivalent, how about including  in
? That appears sufficient for basic_file.o to be compiled correctly,
and it appears to work on the platforms I investigated.

What do you mean by "are you positive"?


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-15 Thread craig dot lawson at centrify dot com


--- Comment #25 from craig dot lawson at centrify dot com  2007-03-15 20:28 
---
(In reply to comment #24)
> Oh, that's excellent news, because we have to include  first
> in  anyway... But now you make me curious!!! If you look at 
> c++config.h
> it doesn't appear do much related to this issue

Sorry, that news was too excellent. It's not true.

The reason I suggested also including  in comment #10 was because I
found  was not enough. I agree that  is perhaps a
poor choice. I think it needs further investigation as to what would be a good
choice.


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-15 Thread craig dot lawson at centrify dot com


--- Comment #27 from craig dot lawson at centrify dot com  2007-03-15 21:17 
---
(In reply to comment #26)

I understand. I'll collect this information from the systems I have, and then
post it here ...


-- 


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



[Bug libstdc++/31117] c++locale.o thread-unsafe in libstdc++

2007-03-22 Thread craig dot lawson at centrify dot com


--- Comment #28 from craig dot lawson at centrify dot com  2007-03-22 23:44 
---
For HP-UX, SunOS, and Irix:

  #if !defined(_POSIX_C_SOURCE)
  # define _POSIX_C_SOURCE 199506L
  #elif _POSIX_C_SOURCE<199506L
  # error "Conflict"
  #endif

  (why would anyone compile C++ with POSIX < 1995.06?)

For AIX, either:

  #define _THREAD_SAFE
  or
  #define _THREAD_SAFE_ERRNO



Details:

HP-UX 11.00, 11.11, 11.22, 11.23:
  errno.h:
#ifdef _REENTRANT
# ifdef _PROTOTYPES
   extern int *__errno(void);
# else 
   extern int *__errno();
# endif
...

  However, errno.h includes  which contains:
/* _REENTRANT selects Posix 1c threads unless draft4 selected.
 * This usage is obsolescent, "-D_POSIX_C_SOURCE=199506" is preferred */
...
#if (_POSIX_C_SOURCE >= 199506) && !defined(_REENTRANT)
# define _REENTRANT
#endif /* _POSIX_C_SOURCE >= 199506 && !_REENTRANT */

  It appears _POSIX_C_SOURCE=199506 is the desired symbol and value, but
  there will be a conflict if intentionally set to something lower (higher
  is OK).

  Confirm using test program:
#include 
int main() {
return errno;
}

  Confirmed: -D_POSIX_C_SOURCE=199506 works.


SunOS 2.6, 7, 5.8, 5.9, 5.10:
  errno.h:
#if (defined(_REENTRANT) || defined(_TS_ERRNO) || \
_POSIX_C_SOURCE - 0 >= 199506L) && !(defined(lint) || defined(__lint))

  Confirmed: -D_POSIX_C_SOURCE=199506 works.


AIX 4.3.3, 5.1:
  errno.h:
#include 
#ifdef _ANSI_C_SOURCE
# if defined(_THREAD_SAFE) || defined(_THREAD_SAFE_ERRNO)
#  define errno   (*_Errno())

  standards.h:
defines _ANSI_C_SOURCE unless overridden by some other model.

  Confirmed: -D_THREAD_SAFE works.
  Confirmed: -D_THREAD_SAFE_ERRNO works.


AIX 5.2:
  errno.h: similar to 4.3.3
  standards.h:
#if defined(_UNIX03)
#  define _THREAD_SAFE
...
#if _XOPEN_SOURCE==600
#  define _THREAD_SAFE
...
Due to statement ordering in this file, if _POSIX_C_SOURCE==200112L before
including this file, then _THREAD_SAFE will be set. Otherwise, this file
sets _POSIX_C_SOURCE==200112L and does not set _THREAD_SAFE.

  Confirmed: -D_THREAD_SAFE works.
  Confirmed: -D_THREAD_SAFE_ERRNO works.
  Confirmed: -D_UNIX03 works. Size effect: sets _POSIX_C_SOURCE==200112L


Irix 6.5:
  errno.h:
#if defined(_SGI_MP_SOURCE) || (_POSIX_C_SOURCE >= 199506L) \
|| (_XOPEN_SOURCE+0 >= 500)
  extern int *__oserror(void);
...

  Confirmed: -D_POSIX_C_SOURCE=199506 works.


-- 


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