Native & viper failures with setjmp exception handling
Port, board and/or hardware
unix
MicroPython version
MicroPython v1.26.0-preview.169.g429478dcfc.dirty on 2025-06-02; linux [GCC 12.2.0] version
(modified from v1.26.0-preview-166-gc0111e63b3)
Reproduction
- grab my branch at https://github.com/jepler/circuitpython/tree/coverage-setjmp
- in ports/unix
make VARIANT=coverage_setjmp test
Expected behaviour
Expected all tests to pass
Observed behaviour
The native_gen.py test fails with a segfault. This is the minimized version of the crashing code:
# catching an exception from .throw()
@micropython.native
def gen3():
try:
yield 1
except Exception as er:
print("caught", repr(er))
g = gen3()
print(g.throw(ValueError(42)))
Additional Information
The branch above has 3 changes:
- introduce a unix variant that uses setjmp for exception handling
- fix a build error in
mp_native_yield_from - turns on N_NLR_SETJMP in emitnative whenever MICROPY_NLR_SETJMP is enabled and N_NLR_SETJMP is not otherwise used (note: this fixes other errors in
make testthat occur with MICROPY_NLR_SETJMP enabled)
It is vaguely possible that my change in mp_native_yield_from is wrong and I considered whether it might contribute to the crash, but in my reduced testcase a gdb breakpoint on that function isn't hit so I don't think that's it.
Code of Conduct
Yes, I agree
mpy-cross viper incompatibility with OBJ_REPR_B
Port, board and/or hardware
unix port, obj_repr_b, x86 (32-bit)
MicroPython version
based on v1.27.0-preview-154-g44986b1f04
Reproduction
- Make a 32-bit REPR_B "standard" or "coverage" build (from e.g., #17688)
- Run
RUN_TESTS_MPY_CROSS_FLAGS="--mpy-cross-flags=\"-march=x86 -msmall-int-bits=30\"" make -C ports/unix/ VARIANT=standard test_full_no_native# orVARIANT=coverage, depending
Expected behaviour
Tests pass
Observed behaviour
12 tests failed: micropython/native_gen.py micropython/native_misc.py micropython/native_try.py micropython/viper_import.py micropython/native_try_deep.py micropython/native_while.py micropython/native_with.py micropython/viper_misc3.py micropython/native_closure.py micropython/native_const.py micropython/native_for.py micropython/viper_with.py
I didn't dig deeply because native & viper were not important to my use case but I think that there are some assumptions about the encoding of small integer values as discussed in a related PR: https://github.com/micropython/micropython/pull/17688#issuecomment-3075383706
} else if (si->vtype == VTYPE_INT || si->vtype == VTYPE_UINT) {
ASM_MOV_REG_IMM(emit->as, reg_dest, (uintptr_t)MP_OBJ_NEW_SMALL_INT(si->data.u_imm));
Additional Information
No, I've provided everything above.
Code of Conduct
Yes, I agree