Nuked-OPL3
Nuked-OPL3 copied to clipboard
NULL pointer dereference in OPL3_EnvelopeUpdateKSL (probably thread race-condition related though)
Hello,
I'm using this cool Nuked-OPL3 implementation in a little emulator project of mine, and encountered a problem. I'm more or less sure that it's my fault, so sorry about reporting as "bug" if it's not a bug of Nuked-OPL3 at all. If this is really the case I would really thank some suggestions.
The problem: recently (worked before very well, for a long time) my emulator always crashes when I try to run an AdLib player tool (also written by me many years ago) inside the emulated machine. Curiously the problem goes away if I compile the emulator with lower optimization level and debug symbols to be able to use gdb
. Since debugging is not so much possible, I dropped in a tons of printf
s throughout the code, and realized that in EnvelopeUpdateKSL()
(called during executing OPL3_GenerateStream()
called from "rendering" audio samples) slot->channel
is a NULL pointer which is dereferenced there, causing the crash.
I guess the problem is probably not a Nuked-OPL3 issue (but I am not sure) but a problem how to use it. I use SDL2 in my emulator, with audio callback which is a thread then from the perspective of the OS. However in the main thread, the emulator also calls function from Nuked-OPL3 when the emulated OPL chip register is written by the software running in my emulation (I use OPL3_WriteRegBuffered()
to do that).
Because the problem seems to go away with no C compiler optimization, the problem seems to be some race condition caused by using Nuked-OPL3 from multiple threads. However if it's true, I cannot easily see any solution to this issue, since I cannot change the major infrastructure of the emulator, SDL audio callback must be a thread (Pushing is not a solution here unfortunately, which is allowed by newer SDL2 versions), while the emulator code itself (which also calls register write events) must be in the "main thread/program".
Hopefully my issue and/or question is understandable, sorry for my lame English, and long text trying to explain what I mean in clumsy way. Please ignore me, if this issue is something you cannot do anything against.
Thanks a lot in advance!
you should probably use a ring buffer to pass writes to the audio thread with shadow register memory for reads on the emulator side