Stream: wasi

Topic: Setting a larger C stack size with WASI SDK


view this post on Zulip Brett Cannon (May 20 2025 at 19:36):

(Apologies if this isn't the right channel for WASI SDK questions, but I couldn't find a better one.)

For CPython, the test suite can't pass with a debug build due to the stack getting blown out. We are doing -z stack-size=16777216 -Wl,--stack-first -Wl,--initial-memory=41943040 which I thought was setting the stack to 16 MiB. But it seems the stack is more like 130K. Am I missing something here?

The Python programming language. Contribute to python/cpython development by creating an account on GitHub.

view this post on Zulip Alex Crichton (May 20 2025 at 19:39):

Do you have a link to the failure of the stack overflow happening? I ask as there are two stack overflows possible:

The flags you link to should fix the first, and AFAIK that's all that should be necessary for the first. The flags you link to don't do anything for the second, though, and that'd require -Wmax-wasm-stack=... options to wasmtime itself.

view this post on Zulip Brett Cannon (May 21 2025 at 16:48):

I already set --wasm maxi-wasm-stack via https://github.com/python/cpython/blob/e1f891414b2329414a6160ed246f5f869a218bfd/Tools/wasm/wasi/__main__.py#L304 which sets it to 16 MiB.

As for a stack trace, part of the problem is Python thinks it's hitting the stack limit via some stack size calculation before it happens as a stack overflow mechanism.

The Python programming language. Contribute to python/cpython development by creating an account on GitHub.

view this post on Zulip Alex Crichton (May 21 2025 at 16:52):

Oh so this is a python-level stack overflow? (a third layer enters the ring!)

view this post on Zulip Brett Cannon (May 21 2025 at 16:59):

Well, it's a Python stack "overflow" in so much as we raise an exception when we think we are going to blow the stack out. Previously there was just a counter, but there was an attempt to make it dynamic in https://github.com/python/cpython/commit/014223649c33b2febbccfa221c2ab7f18a8c0847 (discussed in https://github.com/python/cpython/issues/131770#issuecomment-2755527194). Unfortunately, the calculations do not work when under a debug build of CPython (which, if you remember some of my first wasmtime bug reports, tend to have big objects on the stack). So we are trying to figure out whether the compiler is setting something wrong, whether the calculation mechanism is wrong for WASI, or something else.

* Implement C recursion protection with limit pointers for Linux, MacOS and Windows * Remove calls to PyOS_CheckStack * Add stack protection to parser * Make tests more robust to low stacks * I...
Bug report Bug description: $ python Tools/wasm/wasi.py configure-build-python -- --with-pydebug ... $ python Tools/wasm/wasi.py make-build-python ... $ python Tools/wasm/wasi.py configure-host -- ...

view this post on Zulip Brett Cannon (May 21 2025 at 17:00):

FYI there's also https://github.com/python/cpython/issues/130397 with information on this issue.

Implementing stack overflow protection for webassembly is tricky, as there are two stacks: The hidden webassembly stack The stack used for C stack objects that can have their address taken We need ...

view this post on Zulip Alex Crichton (May 21 2025 at 17:04):

Oh I see so all of this is happening in Python, not in the runtime or in the compiled module layout? If that's the case my usefulness becomes far less as I don't know how Python's stack limits work. It sounds though like you're doing all the right things on the host/linker level so this naively seems unrelated to those options (I could of course be wrong though)

view this post on Zulip Brett Cannon (May 21 2025 at 17:26):

Alex Crichton said:

so all of this is happening in Python, not in the runtime or in the compiled module layout?

Yes and no. "Yes" as in it's a Python mechanism. But "no" because if you look at https://github.com/python/cpython/commit/014223649c33b2febbccfa221c2ab7f18a8c0847 you will see there's an attempt to calculate the C stack depth using C pointers and that isn't working under WASI as expected (or at least compared to other platforms). You can look at Python/ceval.c in that commit to see the crux of the implementation, but it's essentially trying to calculate the stack depth and under WASI the stack appears to be small based on how the calculation is being done and not influenced by the flags (assuming, of course, there are no other bugs :sweat_smile:).

* Implement C recursion protection with limit pointers for Linux, MacOS and Windows * Remove calls to PyOS_CheckStack * Add stack protection to parser * Make tests more robust to low stacks * I...

view this post on Zulip Alex Crichton (May 21 2025 at 17:43):

Hm I may be missing something but that has # define Py_C_STACK_SIZE 80000 for wasi which looks like it's close-ish to your 130k number assuming some "slop"? For WASI should _tstate->c_stack_soft_limit and _tstate->c_stack_hard_limit be configured relative to 0?

view this post on Zulip Alex Crichton (May 21 2025 at 17:44):

insofar that it's known on WASI that the stack bottom is at address 0

view this post on Zulip Alex Crichton (May 21 2025 at 17:44):

so e.g. the hard limit would be ~2k and the soft limit could be ~20k or something like that

view this post on Zulip Brett Cannon (May 21 2025 at 22:20):

I created https://github.com/python/cpython/pull/134469 which just strips out the special limits for WASI and then I disabled the tests that then failed.

Basically I decided it was easier to just let WebAssembly handle the stack protection. :grinning_face_with_smiling_eyes:

Thanks for the help, @Alex Crichton ! Your suggestion to tweak the number inspired me to just rip them out.

Along the way disable some tests which now fail (which were already disabled under Emscripten). This doesn't pose any sercurity risk thanks to WebAssembly's stack protection. Issue: Imple...

view this post on Zulip Ralph (May 22 2025 at 09:00):

Brett Cannon said:

I created https://github.com/python/cpython/pull/134469 which just strips out the special limits for WASI and then I disabled the tests that then failed.

Basically I decided it was easier to just let WebAssembly handle the stack protection. :grinning_face_with_smiling_eyes:

Thanks for the help, Alex Crichton ! Your suggestion to tweak the number inspired me to just rip them out.

violence is always the first way forward, Brett. Have confidence; stride with purpose.

view this post on Zulip Ralph (May 22 2025 at 09:01):

subtlety and civilization come later

view this post on Zulip Brett Cannon (Jun 11 2025 at 20:44):

@Alex Crichton does the stack grow up from 0 or down to 0?

view this post on Zulip Joel Dice (Jun 11 2025 at 21:06):

Down to zero so that the host will trap if it overflows


Last updated: Dec 06 2025 at 06:05 UTC