Ошибка сегментации OpenAL перед основной - PullRequest
3 голосов
/ 30 августа 2011

Я пишу игровой движок на C ++, который использует SDL для графики и OpenAL для аудио. Я занимаюсь разработкой Windows XP, компилирую с MinGW и отлаживаю с помощью GDB. Я обнаружил проблему, когда запустил отладчик, и, даже не достигнув main (), программа получила ошибку сегментации. Я был (и все еще) смущен, почему произошла ошибка, прежде чем программа достигла основного уровня. Однако, несмотря на то, что GDB сказал, что получил SIGSEGV, программа продолжила успешно и работала точно так, как я ожидал (отображенная графика, воспроизводимые звуки, музыка и т. Д.)

Конечно, будучи игровым движком, существует множество различных компонентов, поэтому я избавился от всех компонентов (исключил их из компиляции или закомментировал их) и добавил их обратно, пока не обнаружил, что мои вызовы OpenAL были вызывая segfault. Однако, как ни странно, ошибки по-прежнему происходили за до main, а комментирование вызовов функции OpenAL впоследствии приводило к тому, что segfault прекращался при следующем запуске.

Итак, чтобы проверить свою гипотезу, я сделал отдельный проект с минимальным кодом и связал его только с OpenAL32, и вуаля! Segfault. Это буквально код в полном объеме:

#include <al.h>

int main()
{
    alGetError();
    return 0;
}

Я могу заменить alGetError () на любой другой вызов функции OpenAL (даже alcOpenDevice (), который предназначен для первого вызова библиотеки), и возникает ошибка. Удалите alGetError (), и ошибка исчезнет.

Обратный след непосредственно в точке segfault показывает следующее:

    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 () делает его похожим на проблему потока, когда OpenAL запускается в отдельном потоке, если я не ошибаюсь. Однако я не слишком знаком с многопоточным программированием.

Я скомпилировал свой проект (весь игровой движок, в его текущем состоянии) под Linux, и сообщение segfault не появляется, и программа запускается так, как я ожидал (это означает, что есть еще пара ошибок / segfaults, которые я до сих пор надо исправить, но у меня есть ручка на них: P).

Я не совсем уверен, в чем заключается мой вопрос. Я думаю, я оставлю это с этим вопросом: сигнал segfault, который я получаю, является результатом того, как я реализую / связываю OpenAL, или это что-то вне моего контроля, которое вызывает библиотека OpenAL? Я бы предположил, что это не проблема с самим OpenAL, учитывая широкую базу пользователей библиотеки, но кто знает. Может быть, проблема в том, что я связываю свой проект C ++ с библиотекой C?

ОБНОВЛЕНИЕ : Я исследовал это в течение нескольких дней, и я очень расстроен. Единственные результаты, которые я могу найти для «Segfault перед main»: «У вас есть статический конструктор, который вызывается перед main» и «О, на самом деле это было не до main. Мне нужно научиться использовать отладчик».

Ну, я никогда не слышал о статических конструкторах в C ++. И вообще, я воспроизвел ошибку без каких-либо классов для начала. И я только сталкиваюсь с сигналом segfault, когда использую отладчик, потому что программа работает отлично, если она просто проходит через сигнал (продолжение a.k.a). Помещая точку останова в первую инструкцию в main или даже в main (), segfault происходит до того, как будет достигнута точка останова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...