← index #18168Issue #15944
Off-topic · high · value 0.389
QUERY · ISSUE

Resizing bytearray with active memoryviews corrupts state and segfaults

openby MaksimFengopened 2025-09-29updated 2025-10-20
bug

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

import gc

ba = bytearray(b"abcdefghij")
views = [memoryview(ba) for _ in range(4)]

ba[:] = ba + b"X"*256   

gc.collect()            

for i, mv in enumerate(views):
    mv[0:1] = b"Y"

Expected behaviour

Attempting to resize a bytearray that has active memoryview exports should raise a Python exception and must not corrupt the VM or crash.

Observed behaviour

The resize succeeds; existing memoryviews retain stale pointers to the old buffer. After gc.collect() (or later operations), the VM state gets corrupted and the process segfaults in unrelated code paths (e.g., during enumerate, inside mp_load_method_maybe).

Additional Information

No, I've provided everything above.

Code of Conduct

Yes, I agree

CANDIDATE · ISSUE

FrameBuffer Initialisation fails with ValueError on `memoryview`

closedby corranwebsteropened 2024-10-01updated 2024-10-22
bug

Port, board and/or hardware

RP2; Unix (but I believe this affects any board with framebuffer support)

MicroPython version

MicroPython v1.23.0 on 2024-06-02; Raspberry Pi Pico with RP2040

Reproduction

Run the code below in the REPL, or run a script with the same code in it:

import array
import framebuf
buf = array.array('H', bytearray(2*8*8))
sub_buf = memoryview(buf)[4:]
fbuf = framebuf.FrameBuffer(sub_buf, 4, 8, framebuf.RGB565, 8)

Expected behaviour

I expected the code to work without error.

Observed behaviour

I get an unexpected ValueError with no explanation:

>>> import array
>>> import framebuf
>>> buf = array.array('H', bytearray(2*8*8))
>>> sub_buf = memoryview(buf)[4:]
>>> fbuf = framebuf.FrameBuffer(sub_buf, 4, 8, framebuf.RGB565, 8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 

Additional Information

The "what am I actually trying to do" here is to create a frame buffer on a subsection of another buffer using a memory view to avoid copying data, either:

  • to clip out a sprite from a larger sprite-sheet buffer to display using FrameBuffer.blit
  • to clip drawing to a sub-region of a larger image (for this you have to have a memory view into the same underlying buffer)

This is likely related to, but different from #15571, as that is an issue with bit-alignment. As with that issue, I think that the lines at fault are here: https://github.com/micropython/micropython/blob/17d82344581ad3a76033fae54c5d3304e17f185f/extmod/modframebuf.c#L317-L319

If you look at the underlying buffers, you have something like the following:

....xxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx

where . are values in the underlying buffer that are skipped by the memoryview, x are values that should be visible in the framebuffer, and s are values which are skipped by the stride of 8.

It appears that what the FrameBuffer code is expecting is the following:

....xxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssssxxxx
ssss

even though the last 4 values are never written to.

Work-around

This can be worked around by allocating extra memory to the underlying buffer, although that's fiddly for the first use-case if the data is loaded from an existing sprite sheet buffer, eg. loaded from a file.

Code of Conduct

Yes, I agree

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied