Skip to content

Native builds have no deinitialised guard: pulling a released audiomixer.Mixer dumps core #59

Description

@bdbarnett

Stakes. On the desktop MicroPython and the patched CircuitPython builds,
using an audio node after deinit() is undefined behaviour rather than an
error, and for audiomixer.Mixer it is a segmentation fault. A host that
tears an effect down and pulls a stale reference — a UI holding the old
node, a chain rebuilt while a render is in flight — takes the interpreter
down with it, on hardware where there is no core file to read.

Measured 2026-09-07 against AUDIOIF_PIN 2f6cbc3, one node per process
(audiocomponents/tools/compressor_deinit_use.py, written for exactly this
because a battery that walked all six killed the interpreter):

$ .venv/bin/python tools/compressor_deinit_use.py 3
node 3 Dynamics  RuntimeError: Object has been deinitialized and can no longer be used

$ cmods/bin/micropython ... tools/compressor_deinit_use.py 3
node 3 Dynamics  pulled 1024 bytes

$ cmods/bin/micropython ... tools/compressor_deinit_use.py 5
node 5 Mixer     (SIGSEGV, core dumped)

$ cmods/bin/circuitpython-effects ... tools/compressor_deinit_use.py 5
node 5 Mixer     (SIGSEGV, core dumped)

Indices 1–4 (audioroute.SplitterTap ×2, audiodynamics.Dynamics ×2)
render on as if nothing had happened on both native builds and return the
same bytes they would have returned before the deinit(). Index 5,
audiomixer.Mixer, crashes: its deinit frees the voice buffers and
get_buffer reads them.

The CPython target is the one that behaves: every released node raises
RuntimeError: Object has been deinitialized and can no longer be used, so
the check exists in the shim and not in the native modules.

Ask. The native builds get the same deinitialised guard the CPython
target has, on get_buffer at minimum — an exception, not a crash. The
Mixer is the urgent one because it is the only node measured to fault, but
a tap and a Dynamics returning stale audio silently is the same bug with a
quieter symptom.

Found while closing the Tier 1 deinit() row for Compressor
(audiocomponents/docs/effects/Compressor-evidence.md §2).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions