Skip to content

fix: three crashes found while packaging - #54

Merged
Spacefreak18 merged 3 commits into
Spacefreak18:masterfrom
MrDavid5465:fix/crashes-found-while-packaging
Sep 4, 2026
Merged

fix: three crashes found while packaging#54
Spacefreak18 merged 3 commits into
Spacefreak18:masterfrom
MrDavid5465:fix/crashes-found-while-packaging

Conversation

@MrDavid5465

Copy link
Copy Markdown
Contributor

Split out of #53 at your request — these are bugs the packaging work exposed, not packaging changes. None of them are needed for that PR. Three commits, five files, no build-system or CI changes.

sounddev_init never returns

sounddev_init() is declared int and its last statement was a bare call to usb_generic_shaker_init(...). Falling off the end of a non-void function is undefined behaviour, so new_sound_device() read whatever happened to be in the return register and treated most initialised devices as failures. The PulseAudio streams had in fact connected — visible in qpwgraph — but the devices were freed and never fed telemetry, so nothing shook. Observed as 22 of 24 configured shakers reporting "Could not initialize Sound Device".

One word: return.

--help frees uninitialised pointers

monocoque.c and monocoque-cli.c malloc both Parameters and MonocoqueSettings, then --help / --version / bad parameters goto cleanup_final, which is:

cleanup_final:
    monocoquesettingsfree(ms);
    free(ms);
    freeparams(p);
    free(p);

Every pointer in both structs is freed before any of them was assigned, so malloc leaves them pointing at whatever was in the heap block. Found by installing the released debian-latest .deb on Debian forky, where monocoque --help aborts with free(): invalid pointer; gdb put it in monocoquesettingsfree() called straight from main(). It is undefined behaviour everywhere — forky's glibc is simply the first to check, which is why the same source looks healthy on Debian stable and both Fedoras.

calloc in all three entry points, including monocoque-gui.c, where freeparams() walks the same struct on its early-exit paths.

gmonocoque segfaults on launch for common configs

Three related problems in mgui/uiconfighelper.c, the first of which is a behaviour change worth your judgement:

find_default_config() required sim, api and car to all be present, continue-ing past any entry missing one. conf/monocoque.config — the example the README points at — sets sim and car and never mentions api, so every entry was skipped and the function returned -1. This now treats a missing key as unconstrained rather than disqualifying (absent behaves as "default"). That's the interpretation the shipped example config implies, but if you intended the stricter reading I'll rework it.

The other two are straightforward guards: config_num < 0 now falls back to entry 0 rather than passing -1 to config_setting_get_elem, and selectedconfig / config_devices are NULL-checked, because config_setting_lookup dereferences its argument — which is where it actually died, inside libconfig, before the window was ever drawn.


Verified: builds clean against current master, and monocoque --help runs under MALLOC_CHECK_=3. The original abort was reproduced on Debian forky from the released .deb.

🤖 Generated with Claude Code

MrDavid5465 and others added 3 commits September 3, 2026 17:34
`monocoque --help` aborted with `free(): invalid pointer` on Debian forky --
found by installing the released debian-latest .deb on the distro it is built
for. gdb put it in monocoquesettingsfree() called straight from main().

The early-exit paths (`--help`, `--version`, bad parameters) jump to
cleanup_final before any field of Parameters or MonocoqueSettings is
assigned, and cleanup_final calls monocoquesettingsfree() and freeparams(),
which free every pointer in both. malloc leaves those pointing at whatever
was in the heap block. It is undefined behaviour everywhere; forky's glibc is
simply the first to check, which is why the same source looked healthy on
Debian stable and both Fedoras.

calloc in all three entry points -- monocoque.c, monocoque-cli.c (the `monocoque`
binary) and monocoque-gui.c.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Only 2 of 24 configured sound devices came up -- "Could not initialize Sound
Device" for the other 22 -- and no shaker fired, on a rig whose PipeWire graph
looked perfect: monocoque streams connected into all six filter chains, every
node running.

sounddev_init() is declared int and fell off its end without returning, so
new_sound_device() read whatever was left in the return register and treated
that as the error code. The PulseAudio streams had already connected by then;
the device objects were simply freed and never fed telemetry again, which is
why the graph looked right and nothing shook.

Undefined behaviour, so it varies by build: the same config drives shakers
from a locally compiled monocoque and not from the packaged one. Now returns
usb_generic_shaker_init()'s own result.

Verified against a live Assetto Corsa session on real hardware: 26 devices
initialised, no failures, shakers working.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gmonocoque died before drawing a window, in libconfig:

  #0 config_setting_get_member () from libconfig.so.9
  #1 config_setting_lookup ()
  #2 populate_device_list ()

find_default_config() required sim, api and car to all be present on an
entry and skipped the entry if any lookup failed, so it returned -1;
populate_device_list passed that -1 straight to config_setting_get_elem,
got NULL back, and config_setting_lookup dereferenced it.

No real config has all three. conf/monocoque.config -- the example this
project's own README points at -- sets sim and car and never mentions api,
so this crashed for anyone following the documentation. It stayed hidden in
the Flatpak build only until that manifest was given access to the real
~/.config/monocoque; against an empty config there was nothing to look up.

A key that isn't there no longer disqualifies a match, a -1 falls back to
the first entry (which is what a single-entry config means anyway), and both
NULL paths now return with a message instead of dereferencing. Verified by
rebuilding the Flatpak and launching gmonocoque against the real config that
crashed it: the window opens and stays up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Spacefreak18

Copy link
Copy Markdown
Owner

i might remove some of the comments but this is good.

@Spacefreak18
Spacefreak18 merged commit 8ef05ef into Spacefreak18:master Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants