summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-03-30 10:19:34 +0000
committerSimon Marlow <marlowsd@gmail.com>2011-03-30 10:19:34 +0000
commit035b8ebb5405efbcbfd3474821a877add1feca1e (patch)
tree21268304729a0b1f118593ae912516a0d3070308
parent41147ad2a9ca84ebe66386b3b0043cb7b48ddcd8 (diff)
downloadhaskell-035b8ebb5405efbcbfd3474821a877add1feca1e.tar.gz
Add a debug check for a non-empty FPU stack on x86 (see #4914)
-rw-r--r--rts/RtsStartup.c5
-rw-r--r--rts/RtsUtils.c15
-rw-r--r--rts/RtsUtils.h2
3 files changed, 22 insertions, 0 deletions
diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
index bc169ff0eb..266c04808d 100644
--- a/rts/RtsStartup.c
+++ b/rts/RtsStartup.c
@@ -345,6 +345,11 @@ hs_exit_(rtsBool wait_foreign)
OnExitHook();
+ // sanity check
+#if defined(DEBUG)
+ checkFPUStack();
+#endif
+
// Free the full argv storage
freeFullProgArgv();
diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c
index 3df688f401..8ef6c0d6f2 100644
--- a/rts/RtsUtils.c
+++ b/rts/RtsUtils.c
@@ -323,3 +323,18 @@ int rts_isProfiled(void)
return 0;
#endif
}
+
+// Used for detecting a non-empty FPU stack on x86 (see #4914)
+void checkFPUStack(void)
+{
+#ifdef x86_HOST_ARCH
+ static unsigned char buf[108];
+ asm("FSAVE %0":"=m" (buf));
+
+ if(buf[8]!=255 || buf[9]!=255) {
+ errorBelch("NONEMPTY FPU Stack, TAG = %x %x\n",buf[8],buf[9]);
+ abort();
+ }
+#endif
+}
+
diff --git a/rts/RtsUtils.h b/rts/RtsUtils.h
index 1bf840bb88..b571126828 100644
--- a/rts/RtsUtils.h
+++ b/rts/RtsUtils.h
@@ -46,6 +46,8 @@ void printRtsInfo(void);
/* Alternate to raise(3) for threaded rts, for OpenBSD */
int genericRaise(int sig);
+void checkFPUStack(void);
+
#include "EndPrivate.h"
#endif /* RTSUTILS_H */