[Bug 260456] games/gzdoom: GZDoom 4.1.1 crashes on start-up due to improper use of std::lock_guard

From: <bugzilla-noreply_at_freebsd.org>
Date: Wed, 15 Dec 2021 23:09:48 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=260456

            Bug ID: 260456
           Summary: games/gzdoom: GZDoom 4.1.1 crashes on start-up due to
                    improper use of std::lock_guard
           Product: Ports & Packages
           Version: Latest
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: Individual Port(s)
          Assignee: kevans@freebsd.org
          Reporter: noisetube@gmail.com
          Assignee: kevans@freebsd.org
             Flags: maintainer-feedback?(kevans@freebsd.org)

The GZDoom port might compile ok, but it doesn't run, at least not for me with
FreeBSD/amd64 12.2-RELEASE or 12.3-RELEASE. When I launch it, it crashes and
dumps core while performing sound initialization. After some digging, I found
that the root cause seems to be a bug in the wildmidi_lib.cpp module.

GZDoom supports a number of different options for playing Doom MIDI/MUS music,
one of which is the WildMidi library. The actual WildMidi library is written in
C, but GZDoom includes its own bastardized^Wcustom version which has been
re-written in C++. Internally, wildmidi_lib.cpp uses mutexes when loading patch
files.

The get_patch_data() function in particular makes use of a C++ facility called
std::lock_guard. The salient feature of this facility is that it allows mutexes
to be automatically released when reaching end of scope. This allows you to
take a lock on entry to a function and have the lock automatically released
when the function returns, saving than the programmer having to insert the code
to do this themselves, like an animal.

The only problem is that get_patch_data() recursively calls itself, and if I
understand correctly, you can't use std::lock_guard<std::mutex> with recursive
functions. I'm not sure how this ever worked; maybe you can get away with it
when using GCC. But FreeBSD and Clang/LLVM hate it.

I managed to create a patch that fixes this problem which can be obtained here:

http://people.freebsd.org/~wpaul/gzdoom

You can copy the patch-src_sound_wildmidi_wildmidi_lib.cpp file into
/usr/ports/games/gzdoom/files and rebuild the port, and it should run correctly
now. Instead of using std::lock_guard, the lock is now taken/given directly,
and released before get_patch_data() recursively calls itself.

Note that I am not an expert at C++, so I can't claim that my approach is
entirely correct, but it at least it seems to make GZDoom run.

On a side note, 4.1.1 is a very old version. In the most recent version, the
WildMidi code had been reworked significantly and no longer has this problem.

-- 
You are receiving this mail because:
You are the assignee for the bug.