Skip to content

SEGV crash + garbled audio on aarch64 (Raspberry Pi 5) with Python 3.13 #13

@bartek120

Description

@bartek120

Environment

  • davey: 0.1.4 (cp313-cp313-manylinux_2_17_aarch64 wheel, built with maturin 1.12.6)
  • discord.py: 2.7.1
  • Python: 3.13.5
  • Platform: aarch64 (Raspberry Pi 5, Debian 13 trixie)
  • OS: Linux 6.x aarch64

Issue 1: SEGV crash during voice connection

The Python process receives SIGSEGV (signal 11) during or shortly after a Discord voice connection. The crash occurs consistently within 2-5 seconds of joining a voice channel.

Reproduction:

  1. Bot connects to a voice channel using discord.py 2.7.1
  2. DAVE handshake completes (dave_session.ready = True, can_encrypt = True)
  3. Audio packets start flowing (both receive via decrypt() and send via encrypt_opus())
  4. Process crashes with SEGV within 2-5 seconds
systemd: echo-discord.service: Main process exited, code=killed, status=11/SEGV

The SEGV happens even when davey is not actively called — just having it loaded in the process alongside other native libraries (onnxruntime, soxr) seems to be enough. We confirmed by mocking davey out entirely (sys.modules["davey"] = MagicMock()) — the SEGV stops. Re-enabling real davey → SEGV returns.

Possible cause: Thread safety issue? encrypt_opus() is called from discord.py's AudioPlayer thread while the MLS handshake / decrypt() runs on the asyncio event loop thread. If DaveSession isn't thread-safe, this could cause the crash.

No coredumps available (Pi doesn't have coredumpctl configured), so I can't provide a stack trace.

Issue 2: decrypt() returns success but audio is garbled

When the process doesn't crash, decrypt() reports success (dave_ok=74, dave_fail=0) but the decoded Opus audio is silence or garbled:

DAVE decrypt OK: first speech packet, toc=78, len=45
Discord voice input: first audio from user=..., pcm_len=3840, rms=0.0

The Opus TOC byte (0x78) looks valid and decrypt() doesn't raise an exception, but the decrypted payload produces silence when Opus-decoded (rms=0.0). This means the decrypt output is not valid Opus despite appearing to succeed.

We call set_passthrough_mode(True) before decrypt() (following the discord-ext-voice-recv integration pattern). Without passthrough mode, discord.py's own DAVE path handles decryption first, and our decrypt() call double-decrypts → garbage. With passthrough mode, our decrypt() is the only decryption, but produces garbled output.

Issue 3: encrypt_opus() output not playable by Discord clients

We confirmed encrypt_opus() adds the expected 12-byte DAVE overhead:

test_in = b'\xf8\xff\xfe' * 10  # 30 bytes
test_out = dave_session.encrypt_opus(test_in)
# in=30, out=42 (12 bytes overhead — looks correct)

And can_encrypt=True, dave_session.ready=True, epoch=1. RTCP reports confirm the Discord client receives all packets (perc_loss=0, last_seq increasing). But users cannot hear any audio — Discord clients silently discard the packets.

This was intermittently working (audio was audible in ~1 out of 5 connection attempts), suggesting a timing/race condition in the DAVE session key exchange.

Summary

On aarch64 + Python 3.13:

  1. SEGV within seconds of voice connection (consistent)
  2. decrypt() reports success but produces garbled audio
  3. encrypt_opus() produces output that clients can't decode
  4. All three issues are intermittent/timing-dependent — sometimes a connection works perfectly

Happy to provide more logs or test patches. This is blocking all Discord voice bot functionality on Raspberry Pi.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions