Telechips平台的WinCE下的wave驱动报错的原因

最近公司有个项目使用的百度Carlife语音识别出现wavedev.dll报错问题。根据经验,这种报错问题,一般都是指针越界或者stack over flow等错误。
于是根据wavedev.map文件定位到了midiNote.cpp的函数NoteOn中的数组PitchTable。可仔细分析这个函数以及这个数组,认为怎么都不可能导致内存越

界错误——PitchTable[ Note % 12 ],Note的值怎么都不可能使得引用这个数组时越界。map文件的定位错误的方法有时——尤其是底层驱动层涉及到

硬件上下文的库中,不管用!
为了正确定位出报错的位置,另辟思路,从应用层调用waveOutOpen、waveOutWrite函数开始,加入打印语句,一直追踪这两个API函数的调用过程,看

看哪个打印语句没有打印出来,报错的位置就很有可能出现在这个函数中!为了调查这个问题,也同时将wave驱动的框架弄明白了——我有篇文章大致

介绍了waveOutOpen、waveOutWrite的调用过程。从这个过程中,可以看出PCM数据是如何从应用层流到驱动层的。
遵循着上面的思路,终于在函数OutputStreamContextNonPCM::Render2中定位到了异常:
1、wave驱动层的Render2函数在访问用户的PCM数据时,越界访问!
2、这个函数声明了太多的局部变量,导致stack over flow!
于是针对上面两个错误,给出了如下两个办法:
1、在这个函数里面访问用户数据之前,加入内存边界检查!例如:

if(m_WaveFormatEx.dwChannelMask & SPEAKER_FRONT_LEFT)
{
    if (pCurrData16>=pCurrDataEnd16)//added by zhujw for check PCM data buffer valid
    {
        goto Exit;
    }
    pCurrSamp0[0] = *pCurrData16;
    pCurrData16++;
}

2、将所有占用内存较大的局部变量,全部改为在heap中分配内存。

#if 1 //must use new heap memory .....comment by zhujw 20170630
    LONG *pCurrSamp0 = new LONG[MAXDADONUM];
    LONG *pCurrSamp1 = new LONG[MAXDADONUM];
    LONG *pPrevSamp0 = new LONG[MAXDADONUM];
    LONG *pPrevSamp1 = new LONG[MAXDADONUM];
    LONG *pOutSamp0 = new LONG[MAXDADONUM];
    LONG *pOutSamp1 = new LONG[MAXDADONUM];
#else//if use stack memory,it will be 'Data Abort'....comment by zhujw 20170630
    LONG CurrSamp0[MAXDADONUM];
    LONG CurrSamp1[MAXDADONUM];
    LONG PrevSamp0[MAXDADONUM];
    LONG PrevSamp1[MAXDADONUM];     
    LONG OutSamp0[MAXDADONUM];
    LONG OutSamp1[MAXDADONUM];
#endif

至此,经过测试,问题完美解决!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章