MAME version
0.289 (also confirmed present on current master as of 2026-09-18)
System information
MacBook Pro (Apple Silicon, arm64)
macOS 27.0 (build 26A428)
OSD: sdl3
Summary
MAME crashes with EXC_BAD_ACCESS (SIGSEGV, null pointer) on startup whenever any real sound module is selected (-sound coreaudio, -sound sdl, -sound portaudio, or the default auto) — -sound none is the only value that avoids it. The crash happens during device enumeration in src/osd/modules/sound/coreaudio_sound.cpp, build_device_list(), and is triggered by any connected CoreAudio device that reports more than 66 channels with kAudioChannelLabel_Unknown (0xffffffff) descriptions — in my case an RME Fireface UFX III reporting 94 such channels on both input and output.
There are two independent bugs in this function:
Bug 1 — unbounded array index in the "unknown label" fallback path.
if ((chDesc.mChannelLabel == 0xffffffff) || (chDesc.mChannelLabel >= sMacChannelCount))
{
if (chanLayout->mNumberChannelDescriptions > 1)
{
node.m_port_names.push_back(sMacChannelLabels[desc + 1]);
node.m_port_positions.emplace_back(sChannelPositions[desc + 1]);
}
...
sMacChannelLabels/sChannelPositions are fixed at sMacChannelCount = 67 entries, but desc (the loop index over mNumberChannelDescriptions) is never bounds-checked before being used here. A device with more than 66 channel descriptions (like the 94-channel Fireface) walks straight past the end of both arrays.
Bug 2 — missing comma causes silent string-literal concatenation, leaving a valid in-bounds table entry null.
In the sMacChannelLabels initializer:
"Haptic",
"", "", "",
"Left Top Middle"
"", // 50
"Right Top Middle",
There's no comma after "Left Top Middle", so the C++ compiler concatenates it with the following "" into a single string literal, silently consuming one array slot. Because the array has an explicit size ([sMacChannelCount]), this shifts every subsequent label down by one position and leaves the last slot (index 66, intended for "Right Edge of Screen") implicitly zero-initialized — i.e. a null char*. Any code path that ends up indexing sMacChannelLabels[66] (e.g. bug 1's fallback when desc == 65) then constructs a std::string from a null pointer, which crashes in strlen.
Steps to reproduce
Connect any CoreAudio device (real or virtual) that reports ≥67 channel descriptions with unknown/unlabeled channels, then run:
(or -sound sdl, -sound portaudio, or no -sound flag at all). Crashes on startup during osd_common_t::init_subsystems().
Patch
--- a/src/osd/modules/sound/coreaudio_sound.cpp
+++ b/src/osd/modules/sound/coreaudio_sound.cpp
@@ -75,7 +75,7 @@
"Center Surround Direct",
"Haptic",
"", "", "",
- "Left Top Middle"
+ "Left Top Middle",
"", // 50
"Right Top Middle",
"Left Top Rear",
@@ -1062,7 +1062,7 @@
if ((chDesc.mChannelLabel == 0xffffffff) || (chDesc.mChannelLabel >= sMacChannelCount))
{
- if (chanLayout->mNumberChannelDescriptions > 1)
+ if ((chanLayout->mNumberChannelDescriptions > 1) && ((desc + 1) < sMacChannelCount))
{
node.m_port_names.push_back(sMacChannelLabels[desc + 1]);
node.m_port_positions.emplace_back(sChannelPositions[desc + 1]);
Verified fix: built MAME 0.289 locally with this patch applied; -sound coreaudio, -sound sdl, -sound portaudio, and the default all now start cleanly and repeatedly with the same audio hardware attached.
Happy to open this as a pull request instead if that's preferred.
MAME version
0.289 (also confirmed present on current
masteras of 2026-09-18)System information
MacBook Pro (Apple Silicon, arm64)
macOS 27.0 (build 26A428)
OSD: sdl3
Summary
MAME crashes with
EXC_BAD_ACCESS(SIGSEGV, null pointer) on startup whenever any real sound module is selected (-sound coreaudio,-sound sdl,-sound portaudio, or the defaultauto) —-sound noneis the only value that avoids it. The crash happens during device enumeration insrc/osd/modules/sound/coreaudio_sound.cpp,build_device_list(), and is triggered by any connected CoreAudio device that reports more than 66 channels withkAudioChannelLabel_Unknown(0xffffffff) descriptions — in my case an RME Fireface UFX III reporting 94 such channels on both input and output.There are two independent bugs in this function:
Bug 1 — unbounded array index in the "unknown label" fallback path.
sMacChannelLabels/sChannelPositionsare fixed atsMacChannelCount = 67entries, butdesc(the loop index overmNumberChannelDescriptions) is never bounds-checked before being used here. A device with more than 66 channel descriptions (like the 94-channel Fireface) walks straight past the end of both arrays.Bug 2 — missing comma causes silent string-literal concatenation, leaving a valid in-bounds table entry null.
In the
sMacChannelLabelsinitializer:There's no comma after
"Left Top Middle", so the C++ compiler concatenates it with the following""into a single string literal, silently consuming one array slot. Because the array has an explicit size ([sMacChannelCount]), this shifts every subsequent label down by one position and leaves the last slot (index 66, intended for"Right Edge of Screen") implicitly zero-initialized — i.e. a nullchar*. Any code path that ends up indexingsMacChannelLabels[66](e.g. bug 1's fallback whendesc == 65) then constructs astd::stringfrom a null pointer, which crashes instrlen.Steps to reproduce
Connect any CoreAudio device (real or virtual) that reports ≥67 channel descriptions with unknown/unlabeled channels, then run:
(or
-sound sdl,-sound portaudio, or no-soundflag at all). Crashes on startup duringosd_common_t::init_subsystems().Patch
Verified fix: built MAME 0.289 locally with this patch applied;
-sound coreaudio,-sound sdl,-sound portaudio, and the default all now start cleanly and repeatedly with the same audio hardware attached.Happy to open this as a pull request instead if that's preferred.