From: Andrew STUBBS <andrew.stubbs@st.com>
To: "Dave Korn" <dave.korn@artimi.com>, insight@sources.redhat.com
Subject: Re: MinGW setjmp SEGV
Date: Fri, 05 Aug 2005 14:40:00 -0000 [thread overview]
Message-ID: <op.su1hpkl6o669wz@terrorhawk.bri.st.com> (raw)
In-Reply-To: <SERRANOWm1izAKlydPA000000bd@SERRANO.CAM.ARTIMI.COM>
[-- Attachment #1: Type: text/plain, Size: 1029 bytes --]
On Fri, 05 Aug 2005 15:00:53 +0100, Dave Korn <dave.korn@artimi.com> wrote:
>> The attached patch (code copied from sourceforge) is sufficient to fix
>> the
>> issue. Note that I have included the diff of the whole file and it
>> includes one of the minor changes mentioned above.
>
> That'll be the deleted _INSIDE_CYGWIN_ then?
>
>>
>> Hopefully this patch will help others who have hit the same problem.
>
>
> Hi Andrew,
>
> I was looking through this area just the other day
> (http://sourceware.org/ml/insight/2005-q3/msg00021.html), and ISTM that
> the
> substance of this patch is already in CVS HEAD. The changes appear to
> have
> been added in rev1.9
> (http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/tcl/win/tclWin32Dll.c?cvsr
> oot=src#rev1.9) when tcl 8.4.1 was merged from upstream. Just FYI.
>
>
> cheers,
> DaveK
Many apologies. I have got the diff backwards! It is tcl 8.4.1 that is
broken and AFAIKT CVS HEAD is little altered.
Please find a correct one attached.
Andrew Stubbs
[-- Attachment #2: insight-win.patch --]
[-- Type: application/octet-stream, Size: 5413 bytes --]
--- /view/stubbsa-import/vob/insight.cmp/src/tcl/win/tclWin32Dll.c@@/main/INSIGHT-6.1 2005-07-29 16:22:32.000000000 +0100
+++ /view/stubbsa-import/vob/insight.cmp/src/tcl/win/tclWin32Dll.c 2005-08-05 14:21:03.000000000 +0100
@@ -12,6 +12,10 @@
* RCS: @(#) $Id: tclWin32Dll.c,v 1.16 2002/06/13 09:40:01 vincentdarley Exp $
*/
+/* The following is a workaround for a w32api problem.
+ See http://sources.redhat.com/ml/insight/2004-q4/msg00039.html */
+#define __INSIDE_CYGWIN__
+
#include "tclWinInt.h"
/*
@@ -38,6 +42,23 @@
static int platformId; /* Running under NT, or 95/98? */
#ifdef HAVE_NO_SEH
+/*
+ * Unlike Borland and Microsoft, we don't register exception handlers by
+ * pushing registration records onto the runtime stack. Instead, we register
+ * them by creating an EXCEPTION_REGISTRATION within the activation record.
+ */
+
+typedef struct EXCEPTION_REGISTRATION {
+ struct EXCEPTION_REGISTRATION *link;
+ EXCEPTION_DISPOSITION (*handler)(
+ struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
+ void *ebp;
+ void *esp;
+ int status;
+} EXCEPTION_REGISTRATION;
+#endif
+
+#ifdef HAVE_NO_SEH
static void *ESP;
static void *EBP;
#endif /* HAVE_NO_SEH */
@@ -347,65 +368,111 @@
int
TclpCheckStackSpace()
{
+
+#ifdef HAVE_NO_SEH
+ EXCEPTION_REGISTRATION registration;
+#endif
int retval = 0;
/*
- * We can recurse only if there is at least TCL_WIN_STACK_THRESHOLD
- * bytes of stack space left. alloca() is cheap on windows; basically
- * it just subtracts from the stack pointer causing the OS to throw an
- * exception if the stack pointer is set below the bottom of the stack.
+ * We can recurse only if there is at least TCL_WIN_STACK_THRESHOLD bytes
+ * of stack space left. alloca() is cheap on windows; basically it just
+ * subtracts from the stack pointer causing the OS to throw an exception
+ * if the stack pointer is set below the bottom of the stack.
*/
#ifdef HAVE_NO_SEH
__asm__ __volatile__ (
- "movl %esp, _ESP" "\n\t"
- "movl %ebp, _EBP");
- __asm__ __volatile__ (
- "pushl $__except_checkstackspace_handler" "\n\t"
- "pushl %fs:0" "\n\t"
- "mov %esp, %fs:0");
-#else
+ /*
+ * Construct an EXCEPTION_REGISTRATION to protect the call to __alloca
+ */
+
+ "leal %[registration], %%edx" "\n\t"
+ "movl %%fs:0, %%eax" "\n\t"
+ "movl %%eax, 0x0(%%edx)" "\n\t" /* link */
+ "leal 1f, %%eax" "\n\t"
+ "movl %%eax, 0x4(%%edx)" "\n\t" /* handler */
+ "movl %%ebp, 0x8(%%edx)" "\n\t" /* ebp */
+ "movl %%esp, 0xc(%%edx)" "\n\t" /* esp */
+ "movl %[error], 0x10(%%edx)" "\n\t" /* status */
+
+ /*
+ * Link the EXCEPTION_REGISTRATION on the chain
+ */
+
+ "movl %%edx, %%fs:0" "\n\t"
+
+ /*
+ * Attempt a call to __alloca, to determine whether there's sufficient
+ * memory to be had.
+ */
+
+ "movl %[size], %%eax" "\n\t"
+ "pushl %%eax" "\n\t"
+ "call __alloca" "\n\t"
+
+ /*
+ * Come here on a normal exit. Recover the EXCEPTION_REGISTRATION and
+ * store a TCL_OK status
+ */
+
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl %[ok], %%eax" "\n\t"
+ "movl %%eax, 0x10(%%edx)" "\n\t"
+ "jmp 2f" "\n"
+
+ /*
+ * Come here on an exception. Get the EXCEPTION_REGISTRATION that we
+ * previously put on the chain.
+ */
+
+ "1:" "\t"
+ "movl %%fs:0, %%edx" "\n\t"
+ "movl 0x8(%%edx), %%edx" "\n\t"
+
+ /*
+ * Come here however we exited. Restore context from the
+ * EXCEPTION_REGISTRATION in case the stack is unbalanced.
+ */
+
+ "2:" "\t"
+ "movl 0xc(%%edx), %%esp" "\n\t"
+ "movl 0x8(%%edx), %%ebp" "\n\t"
+ "movl 0x0(%%edx), %%eax" "\n\t"
+ "movl %%eax, %%fs:0" "\n\t"
+
+ :
+ /* No outputs */
+ :
+ [registration] "m" (registration),
+ [ok] "i" (TCL_OK),
+ [error] "i" (TCL_ERROR),
+ [size] "i" (TCL_WIN_STACK_THRESHOLD)
+ :
+ "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"
+ );
+ retval = (registration.status == TCL_OK);
+
+#else /* !HAVE_NO_SEH */
__try {
-#endif /* HAVE_NO_SEH */
+#ifdef HAVE_ALLOCA_GCC_INLINE
+ __asm__ __volatile__ (
+ "movl %0, %%eax" "\n\t"
+ "call __alloca" "\n\t"
+ :
+ : "i"(TCL_WIN_STACK_THRESHOLD)
+ : "%eax");
+#else
alloca(TCL_WIN_STACK_THRESHOLD);
+#endif /* HAVE_ALLOCA_GCC_INLINE */
retval = 1;
-#ifdef HAVE_NO_SEH
- __asm__ __volatile__ (
- "jmp checkstackspace_pop" "\n"
- "checkstackspace_reentry:" "\n\t"
- "movl _ESP, %esp" "\n\t"
- "movl _EBP, %ebp");
-
- __asm__ __volatile__ (
- "checkstackspace_pop:" "\n\t"
- "mov (%esp), %eax" "\n\t"
- "mov %eax, %fs:0" "\n\t"
- "add $8, %esp");
-#else
} __except (EXCEPTION_EXECUTE_HANDLER) {}
#endif /* HAVE_NO_SEH */
-
- /*
- * Avoid using control flow statements in the SEH guarded block!
- */
+
return retval;
}
-#ifdef HAVE_NO_SEH
-static
-__attribute__ ((cdecl))
-EXCEPTION_DISPOSITION
-_except_checkstackspace_handler(
- struct _EXCEPTION_RECORD *ExceptionRecord,
- void *EstablisherFrame,
- struct _CONTEXT *ContextRecord,
- void *DispatcherContext)
-{
- __asm__ __volatile__ (
- "jmp checkstackspace_reentry");
- return 0; /* Function does not return */
-}
-#endif /* HAVE_NO_SEH */
+
\f
/*
*----------------------------------------------------------------------
next prev parent reply other threads:[~2005-08-05 14:40 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-05 13:44 Andrew STUBBS
2005-08-05 14:01 ` Dave Korn
2005-08-05 14:40 ` Andrew STUBBS [this message]
2005-08-05 15:28 ` Dave Korn
2005-08-05 15:57 ` Andrew STUBBS
2005-08-05 16:35 ` Dave Korn
2005-08-05 21:43 ` Steven Johnson
2005-08-08 9:38 ` Andrew STUBBS
2005-09-21 2:25 ` Dave Murphy
2005-09-21 9:00 ` Andrew STUBBS
2005-09-21 21:25 ` Dave Murphy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=op.su1hpkl6o669wz@terrorhawk.bri.st.com \
--to=andrew.stubbs@st.com \
--cc=dave.korn@artimi.com \
--cc=insight@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).