Nuked-OPL3 icon indicating copy to clipboard operation
Nuked-OPL3 copied to clipboard

NULL pointer dereference in OPL3_EnvelopeUpdateKSL (probably thread race-condition related though)

Open lgblgblgb opened this issue 3 years ago • 1 comments

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 printfs 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!

lgblgblgb avatar Jun 09 '21 13:06 lgblgblgb

you should probably use a ring buffer to pass writes to the audio thread with shadow register memory for reads on the emulator side

kmar avatar Dec 23 '21 08:12 kmar