[Python-Dev] test_sre.py fails on Win64 because PyOS_CheckStack *never* fails
Trent Mick
trentm@ActiveState.com
Mon, 9 Oct 2000 15:56:00 -0700
[Trent notes that PyOS_CheckStack never fails on Win64 hence test_[s]re.py
fail on the overflow checks]
[Fredrik gives me a simple test C program to test PyOS_CHeckStack
independently (The test program is included at the bottom of this
email.)]
SOrry I took so long to reply to this but I spent a little bit of time
playing with PyOS_CheckStack on Win32 and Win64 and I am now just frustrated.
Here is what I found:
- The simple test program shows that PyOS_CheckStack will fire as intended
on both Win32 and Win64 with either Visual C's default optimization OR no
optimization.
- The simple test program will *not* fire as intended with the '-O2'
optimization which Python *does* use for pythonrun.c (where
PyOS_CheckStack lives). So, likely the '-O2' optimization will
optimize-away the _alloca() call. Fine. But why then does it *not* get
optimized away when pythonrun.c is compiled? Does the context around other
code in the same file affect that optimization?
- When I apply this patch to _sre.c on *Win32* (basically the same test as
the test file that Fredrik gave me to try) the "callme(0)" call *never*
returns -- infinite loop. Note that this happens on the Release *and* Debug
builds so nothing is being optimized away.
***************
*** 560,565 ****
--- 560,569 ----
}
#endif
+
+
+ void callme(int i);
+
LOCAL(int)
SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
{
***************
*** 578,583 ****
--- 582,588 ----
TRACE(("|%p|%p|ENTER %d\n", pattern, ptr, level));
#if defined(USE_STACKCHECK)
+ callme(0);
if (level % 10 == 0 && PyOS_CheckStack())
return SRE_ERROR_RECURSION_LIMIT;
#endif
***************
*** 2337,2340 ****
--- 2342,2357 ----
Py_InitModule("_" MODULE, _functions);
}
+ void callme(int i)
+ {
+ char buf[100000];
+ if (PyOS_CheckStack())
+ return;
+ printf("%d\n", i);
+ memset(buf, 0, sizeof buf);
+ callme(i+1);
+ }
+
+
+
#endif /* !defined(SRE_RECURSIVE) */
- I am not smart enough and/or (you decide :) do not have the inclination to
figure this out (i.e. start looking at assembly code) just so _sre can use
stack checking instead of the existing RECURSION_LIMIT framework (albeit
the limited general usefullness of this) on Win64 so that test_sre.py can
pass.
Would it be alright for me to apply:
*** python/dist/src/Include/pythonrun.h Sat Sep 16 09:31:31 2000
--- python/dist/src/Include/pythonrun.h Sun Oct 8 10:20:02 2000
***************
*** 88,94 ****
to a 8k margin. */
#define PYOS_STACK_MARGIN 2048
! #if defined(WIN32) && defined(_MSC_VER)
/* Enable stack checking under Microsoft C */
#define USE_STACKCHECK
#endif
--- 88,94 ----
to a 8k margin. */
#define PYOS_STACK_MARGIN 2048
! #if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER)
/* Enable stack checking under Microsoft C */
#define USE_STACKCHECK
#endif
to disable stack checking on Win64 until Win64 become more mainstream and
others can bang away at this? The important thing, I would think, is
getting the test suite passing for Python 2.0.
------- test file mentioned above --------------------------------
#include <malloc.h>
#include <excpt.h>
int __inline
PyOS_CheckStack()
{
__try {
_alloca(100000);
return 0;
} __except (EXCEPTION_EXECUTE_HANDLER) {
/* just ignore all errors */
}
return 1;
}
void
callme(int i)
{
char buf[100000];
if (PyOS_CheckStack())
return;
printf("%d\n", i);
memset(buf, 0, sizeof buf);
callme(i+1);
}
int
main()
{
callme(0);
}
-----------------------------------------------------
--
Trent Mick
TrentM@ActiveState.com