替换FAudio回调实现为普通函数后触发段错误问题排查
FAudio全局函数回调导致段错误问题
我正在使用FAudio(XAudio2的跨平台替代库)。原本我通过继承FAudioVoiceCallback类实现回调,代码可正常运行:
class FAudio_BufferNotify : public FAudioVoiceCallback { public: HANDLE hBufferEndEvent; FAudio_BufferNotify() { hBufferEndEvent = NULL; hBufferEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL); assert(hBufferEndEvent != NULL); } ~FAudio_BufferNotify() { CloseHandle(hBufferEndEvent); hBufferEndEvent = NULL; } STDMETHOD_(void, OnBufferEnd) (void* pBufferContext) { assert(hBufferEndEvent != NULL); SetEvent(hBufferEndEvent); } // 空实现: STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32 BytesRequired) {} STDMETHOD_(void, OnVoiceProcessingPassEnd) () {} STDMETHOD_(void, OnStreamEnd) () {} STDMETHOD_(void, OnBufferStart) (void* pBufferContext) {} STDMETHOD_(void, OnLoopEnd) (void* pBufferContext) {} STDMETHOD_(void, OnVoiceError) (void* pBufferContext, HRESULT Error){}; };
但该实现依赖COM调用,跨平台性较差,因此我改为使用普通全局函数实现回调:
void OnBufferEnd(void * pBufferContext) { assert(hBufferEndEvent != NULL); SetEvent(hBufferEndEvent); } void OnVoiceProcessingPassStart(uint32_t BytesRequired) {} void OnVoiceProcessingPassEnd() {} void OnStreamEnd() {} void OnBufferStart(void * pBufferContext) {} void OnLoopEnd(void * pBufferContext) {} void OnVoiceError(void * pBufferContext, uint32_t Error) {}
代码可正常编译,但运行时触发段错误。通过lldb调试发现问题与OnVoiceProcessingPassStart相关,期望程序能正常加载并播放音频,以下是lldb的回溯信息:
* thread #8, stop reason = Exception 0xc0000005 encountered at address 0x7ff6e05de8dc: Access violation reading location 0xffffffffffffffff frame #0: 0x00007ff6e05de8dc visualboyadvance-m.exe`FAudio_INTERNAL_MixSource(voice=0x00000249d9bbc150) at FAudio_internal.c:829:3 826 FAudio_PlatformUnlockMutex(voice->audio->sourceLock); 827 LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock) 828 -> 829 voice->src.callback->OnVoiceProcessingPassStart( 830 voice->src.callback, 831 FAudio_INTERNAL_GetBytesRequested(voice, (uint32_t) toDecode) 832 ); (lldb) bt * thread #8, stop reason = Exception 0xc0000005 encountered at address 0x7ff6e05de8dc: Access violation reading location 0xffffffffffffffff * frame #0: 0x00007ff6e05de8dc visualboyadvance-m.exe`FAudio_INTERNAL_MixSource(voice=0x00000249d9bbc150) at FAudio_internal.c:829:3 frame #1: 0x00007ff6e05dc227 visualboyadvance-m.exe`FAudio_INTERNAL_GenerateOutput(audio=0x00000249d9b9d490, output=0x00000249d9bb38e0) at FAudio_internal.c:1337:4 frame #2: 0x00007ff6e05dbea7 visualboyadvance-m.exe`FAudio_INTERNAL_UpdateEngine(audio=0x00000249d9b9d490, output=0x00000249d9bb38e0) at FAudio_internal.c:1435:3 frame #3: 0x00007ff6e05e20fc visualboyadvance-m.exe`FAudio_INTERNAL_MixCallback(userdata=0x00000249d9b9d490, stream="", len=3840) at FAudio_platform_sdl2.c:46:3 frame #4: 0x00007ff6e05215fd visualboyadvance-m.exe`SDL_RunAudio + 317 frame #5: 0x00007ff6e0514539 visualboyadvance-m.exe`SDL_RunThread + 41 frame #6: 0x00007ff6e056480e visualboyadvance-m.exe`RunThreadViaCreateThread + 14 frame #7: 0x00007ff98687257d kernel32.dll`BaseThreadInitThunk + 29 frame #8: 0x00007ff98866aa58 ntdll.dll`RtlUserThreadStart + 40
内容的提问来源于stack exchange,提问作者Zach Bacon
相关产品推荐
相关产品推荐

