OpenAL Segmentation Fault Before Main
I'm writing a game engine in C++ that utilizes SDL for graphics and OpenAL for audio. I'm developing on Windows XP compiling with MinGW and debugging with GDB. I discovered the problem when I ran the debugger and, before even reaching main(), the program received a Segmentation Fault. I was (and still am) confused why a segfault would occur before the program reached main. However, even though GDB said it received SIGSEGV, the program continued happily and ran exactly as I would expect it to (displayed graphics, played sounds, music, etc.)
Of course, being a game engine, there are a lot of different components, so I got rid of all components (excluded them from compiling or commented them out) and added them back in until I discovered that my calls to OpenAL were causing the segfault. Oddly enough though, the segfaults still occurred before main, and commenting out the OpenAL function calls subsequently caused the segfault to stop occurring on the next run.
So, to test out my hypothesis, I made a separate project with minimal code and linked only with OpenAL32, and voila! Segfault. This is literally the code in its entirety:
#include <al.h>
int main()
{
alGetError();
return 0;
}
I can replace alGetError() with any other OpenAL function call (even alcOpenDevice(), which is designed to be the first library call), and the segfault occurs. Remove alGetError(), and the segfault disappears.
The backtrace directly at the point of the segfault shows the following:
Program received signal SIGSEGV, Segmentation fault.
0x7c918af2 in ntdll!RtlpWaitForCriticalSection ()
from C:\WINDOWS\system32\ntdll.dll
(gdb) bt
#0 0x7c918af2 in ntdll!RtlpWaitForCriticalSection ()
from C:\WINDOWS\system32\ntdll.dll
#1 0x7c901046 in ntdll!RtlEnumerateGenericTableLikeADirectory ()
from C:\WINDOWS\system32\ntdll.dll
#2 0x00e461a0 in ?? ()
#3 0x77dd6cd8 in RegCloseKey () from C:\WINDOWS\system32\advapi32.dll
#4 0x77dde88d in RegCreateKeyExA () from C:\WINDOWS\system32\advapi32.dll
#5 0x77de473f in RegCreateKeyA () from C:\WINDOWS\system32\advapi32.dll
#6 0x6650127a in ?? () from C:\WINDOWS\system32\wbsys.dll
#7 0x7c90118a in ntdll!LdrSetAppCompatDllRedirectionCallback ()
from C:\WINDOWS\system32\ntdll.dll
#8 0x66500000 in ?? ()
#9 0x7c91c342 in ntdll!LdrHotPatchRoutine ()
from C:\WINDOWS\system32\ntdll.dll
#10 0x7c915c69 in ntdll!RtlValidateUnicodeString ()
from C:\WINDOWS\system32\ntdll.dll
#11 0x7c915dcb in ntdll!LdrShutdownProcess ()
from C:\WINDOWS\system32\ntdll.dll
#12 0x00000000 in ?? ()
RtlpWaitForCriticalSection() makes it seem like a thread issue, which OpenAL runs in a separate thread if I'm not mistaken. However I'm not too familiar with multithreaded programming.
I compiled my project (the whole game engine, in its current state) under Linux and no segfault message occurs, and the program runs as I would expect it to (this means there are a couple other errors/segfaults that I still have to fix up but I have a handle on them :P).
I'm not sure exactly what my question is. I guess I'll leave it with this question: is the segfault signal I'm receiving a result of the way I'm implementing/linking OpenAL, or is it something beyond my control that the OpenAL library causes? I would assume it's not a problem with OpenAL itself, considering the broad user base of the library, but who knows. Maybe it's a problem with the fact that I am linking my C++ project to a C library?
UPDATE : I've been researching this for a few days now, and I'm getting very 开发者_如何学Gofrustrated. The only results I can find for "Segfault before main" are: "You have a static constructor, which is called before main" and "Oh, it actually wasn't before main. I need to learn how to use a debugger."
Well, I've never heard of static constructors in C++. And anyway, I reproduced the error without any classes to begin with. And I only run into the segfault signal when I'm using the debugger, because the program runs perfectly if it just blasts through the signal (a.k.a continuing). Putting a breakpoint on the first instruction in main or even on main(), the segfault occurs before the breakpoint is hit.
精彩评论