This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
gen-num-limits runs forever on GNU/Linux/sparc (Red Hat Linux 6.2)
- To: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Subject: gen-num-limits runs forever on GNU/Linux/sparc (Red Hat Linux 6.2)
- From: Alexandre Oliva <aoliva at redhat dot com>
- Date: 31 Jan 2001 05:26:56 -0200
- Organization: GCC Team, Red Hat
The problem is that longjmp shouldn't generally be used to return from
a signal, because it doesn't necessarily restore the blocked-signals
mask. So, after the first trap longjmp()s out of the signal handler,
SIGFPE is blocked, and the second trap is never delivered. This patch
arranges for us to use sigsetjmp if available, falling back to
setjmp/longjmp otherwise. According to the GNU/Linux man-pages,
setjmp/longjmp would save the signal mask on BSD4.3, but not on SysV,
so it's probably ok to use it if sigsetjmp is not available.
Tested on sparc-unknown-linux-gnu, with and without -DHAVE_SIGSETJMP.
The latter compiled, but would never complete, as before. Ok to
install?
Index: libstdc++-v3/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* src/gen-num-limits.cc: Use sigsetjmp and siglongjmp if possible.
* mknumeric_limits: Try to compile it with -DHAVE_SIGSETJMP first,
and retry without it if it fails.
Index: libstdc++-v3/mknumeric_limits
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/mknumeric_limits,v
retrieving revision 1.7
diff -u -p -r1.7 mknumeric_limits
--- libstdc++-v3/mknumeric_limits 2000/12/22 08:15:27 1.7
+++ libstdc++-v3/mknumeric_limits 2001/01/31 07:15:12
@@ -178,18 +178,23 @@ namespace std {
EOF
-echo "$CXX $CPPFLAGS -I$BUILD_DIR/include \
+echo "$CXX $CPPFLAGS -I$BUILD_DIR/include -DHAVE_SIGSETJMP \
-o "$BUILD_DIR/src/gen-num-limits" "$SRC_DIR/src/gen-num-limits.cc" \
$LDFLAGS"
-$CXX $CPPFLAGS -I$BUILD_DIR/include \
+{
+ $CXX $CPPFLAGS -I$BUILD_DIR/include -DHAVE_SIGSETJMP \
-o "$BUILD_DIR/src/gen-num-limits" "$SRC_DIR/src/gen-num-limits.cc" \
$LDFLAGS
-
-if [ ! -f "$BUILD_DIR/src/gen-num-limits" ]; then
+} || {
+ echo "Failed, retrying without -DHAVE_SIGSETJMP...";
+ $CXX $CPPFLAGS -I$BUILD_DIR/include \
+ -o "$BUILD_DIR/src/gen-num-limits" "$SRC_DIR/src/gen-num-limits.cc" \
+ $LDFLAGS;
+} || {
echo "gen-num-limits failed to build, exiting."
exit 1
-fi
+}
"$BUILD_DIR/src/gen-num-limits" >> $OUT_H-t
Index: libstdc++-v3/src/gen-num-limits.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/src/gen-num-limits.cc,v
retrieving revision 1.6
diff -u -p -r1.6 gen-num-limits.cc
--- libstdc++-v3/src/gen-num-limits.cc 2001/01/17 07:13:39 1.6
+++ libstdc++-v3/src/gen-num-limits.cc 2001/01/31 07:15:13
@@ -57,6 +57,18 @@
#include <wchar.h>
#endif
+// mknumeric_limits will first try to compile this file with
+// HAVE_SIGSETJMP. If it fails, then it will try without it. Some
+// systems, such as GNU/Linux/sparc, would remain with the signal
+// blocked if the signal handler uses longjmp instead of siglongjmp.
+// We assume here setjmp/longjmp will preserve the sigblock mask if
+// sigsetjmp is not present.
+
+#if ! HAVE_SIGSETJMP
+# define sigjmp_buf jmp_buf
+# define sigsetjmp(buf, save) setjmp (buf)
+# define siglongjmp(env, ret) longjmp (env, ret)
+#endif
const char tab[] = " ";
const char tab2[] = " ";
@@ -90,7 +102,7 @@ const int integer_base_rep = 2;
// occur for int, unsigned, long, unsigned long. Furthermore
// overflow cannot happen for unsigned integer types.
-jmp_buf env;
+sigjmp_buf env;
/* The prototype of signal() may vary. Accomodate variations such as
void(*)(int) and void(*)(...). */
@@ -112,13 +124,13 @@ void signal_handler(int sig)
sigemptyset (&x);
sigprocmask(SIG_SETMASK, &x, NULL);
#endif /* __CYGWIN__ */
- longjmp(env, sig);
+ siglongjmp(env, sig);
}
template<typename Operation>
bool trapping(const Operation& op)
{
- if (setjmp(env) == 0) op();
+ if (sigsetjmp(env, 1) == 0) op();
else return true;
return false;
}
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me