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
Viper: ptr8(0)[0] = 1 causes SIGSEGV on unix port
Port, board and/or hardware
Unix
MicroPython version
MicroPython v1.27.0-preview.107.gd1607598f on 2025-09-09; linux [GCC 14.2.0] version
Reproduction
try:
import micropython
except ImportError:
print("SKIP missing micropython")
else:
try:
@micropython.viper
def poke0():
p = ptr8(0)
p[0] = 1
try:
poke0()
print("should not reach here")
except Exception as e:
print("EXC", type(e).__name__)
except AttributeError:
print("SKIP viper_not_available")
Expected behaviour
it would be helpful if either:
- Viper rejected obviously invalid addresses like 0 (and perhaps addr + size overflow) with a Python exception in a debug/safe build mode, or
- The docs explicitly call out that such code will crash the process.
Observed behaviour
The process crashes with SIGSEGV at the generated Viper instruction
[#0] 0x7ffff7fba051 → mov BYTE PTR [rbx], dl
[#1] 0x7ffff7e27f40 → rex.WX sbb rax, QWORD PTR [rax]
[#2] 0x5555555f39e4 → mp_cstack_usage()
[#3] 0x7ffff7e27b60 → rcr ch, 1
Additional Information
No, I've provided everything above.
Code of Conduct
Yes, I agree