-
-
Notifications
You must be signed in to change notification settings - Fork 32k
GH-113655: Lower the C recursion limit for some platforms #124264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Include/cpython/pystate.h
Outdated
@@ -206,7 +206,7 @@ struct _ts { | |||
// A debug build is likely built with low optimization level which implies | |||
// higher stack memory usage than a release build: use a lower limit. | |||
# define Py_C_RECURSION_LIMIT 500 | |||
#elif defined(__s390x__) | |||
#elif defined(__BIG_ENDIAN__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment explaining why big endian has a lower limit, with gh-113655
reference.
That's strange that all big endian archs allocates more memory on the stack. What can explain that only big endian archs are affected? |
I think it's a coincidence, and the logic is more related to the fact that big endian architectures aren't tested much. Perhaps the more appropriate logic would be to have a "more conservative" value in the default branch, and make it higher for platforms that we know are safe. |
Ok, so I've played a bit with godbolt and got the following numbers for a dummy function with no args or variables:
So, looks like ppc64/s390/SPARC are the platforms with unusually large stack frames. However, I don't see any obvious relation between byte order and stack frame size here. ppc64le's is only a little smaller than ppc64 BE, so I have no clue why we're hitting the crash with one but not the other — but maybe it just happened to be on the border. On all other biendian arches, stack frame seems to be of the same size on both variants. I've used the following code: void b() {
}
void a() {
b();
} Tested with various compilers, compiler options ( |
Would it be possible to only use lower limit on these 3 archs? Rather than testing "big endian". |
Yeah, I suppose so. @thesamesam also mentioned HPPA, but godbolt doesn't cover that. |
Include/cpython/pystate.h
Outdated
@@ -206,7 +206,7 @@ struct _ts { | |||
// A debug build is likely built with low optimization level which implies | |||
// higher stack memory usage than a release build: use a lower limit. | |||
# define Py_C_RECURSION_LIMIT 500 | |||
#elif defined(__s390x__) | |||
#elif defined(__BIG_ENDIAN__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#elif defined(__BIG_ENDIAN__) | |
#elif defined(__hppa__) || defined(__powerpc64__) || defined(__s390__) || defined(__sparc__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or we could try to use different values for different arches, given that ppc64 could probably use a higher value. Probably worth double-checking SPARC64, as it has even bigger frames than s390x.
I saw this question just before I went to bed and my assumption (which I wanted to prove/disprove today) was that it was an unfortunate artefact of ABI design and that if we ended up looking at the ABIs for newer (and therefore LE) arches, we'd end up seeing some notable differences. But mgorny (thank you!) beat me to it and I think his analysis is right. I'll look a bit more then update this PR. Thanks again both. |
Ok, now for some real hardware testing of when
It looks like amd64/x86/etc. are hitting some other issue that looks like a 16-bit signed counter. The values I've gotten for PPC64 suggests that LE was on the edge already. Surprisingly, my value for s390x is much higher than the one currently used — FWICS it was lowered due to buildbots failing. Honestly, I don't know what values to put here. |
cf94932
to
7bbca61
Compare
@vstinner, with Sam's permission, I have pushed a commit that lowers the limits on PPC64 and SPARC instead. |
Lower the C recursion limit for HPPA, PPC64 and SPARC, as they use relatively large stack frames that cause e.g. `test_descr` to hit a stack overflow. According to quick testing, it seems that values around 8000 are max for HPPA and PPC64 (ELFv1 ABI) and 7000 for SPARC64. To keep things safe, let's use 5000 for PPC64 and 4000 for SPARC. Co-authored-by: Sam James <[email protected]>
7bbca61
to
11c554a
Compare
Thanks! Happy now. @vstinner Can you take another look please? |
Merged, thanks. The final commit is way better than the first iteration only checking for big endian ;-) |
Thanks a lot! |
Lower the C recursion limit for HPPA, PPC64 and SPARC, as they use
relatively large stack frames that cause e.g.
test_descr
to hita stack overflow. According to quick testing, it seems that values
around 8000 are max for HPPA and PPC64 (ELFv1 ABI) and 7000 for SPARC64.
To keep things safe, let's use 5000 for PPC64 and 4000 for SPARC.
Co-authored-by: Sam James [email protected]