You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

替换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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:07:13