在C ++中跟踪随机发生的C0000005访问冲突有哪些有用的提示?

时间:2012-11-19 03:18:01

标签: c++ memory pointers access-violation heap-corruption

我已经在这里进行了一些搜索,MSDN以及通过谷歌试图找到任何解决方案的其他论坛,但到目前为止仍然卡住了。

我一直在寻找一周,试图在我的C ++程序中追踪访问冲突错误。我不能在这里发布代码,因为它在某些IP限制下,但基本上,它是一个循环,大约每100ms从TCP连接读取字节并将它们放在std :: queue的背面。

在我注意到特定字节序列通过后,我从队列中删除x个字节并将其作为内部协议中定义的消息处理。

发生的情况是,在我的应用程序内部,队列正在损坏并导致应用程序崩溃。因此,对于它是一个访问冲突的事实,它必须是一个狡猾的指针。

我曾尝试使用VS2005 Debugger和Windbg来查找它,我有调用堆栈来查看,但它没有多大帮助。我可以解决的是原因是内部队列损坏了。它崩溃的原因是因为消息的头部被发送解析,但是因为它被破坏了所有东西都会崩溃。

然后我尝试了英特尔线程检查器,但是在这个应用程序中使用它太慢了,因为我的程序是同步多线程系统的一部分。

有时会运行300次读取...有时它可以执行5000次读取...有时它可以在崩溃之前执行10000次读取。

我可以尝试哪些其他诊断途径?我错过了一些简单的东西,我应该已经检查过了吗?从我所看到的,任何新的东西都有一个匹配的删除,我使用Boost Librarys在长寿命对象上使用共享指针和自动指针。

2 个答案:

答案 0 :(得分:3)

使用SEH(结构化异常处理)找出哪个部分引发AV。

来自MSDN的C ++示例代码中的SEH。

#include <stdio.h>
#include <windows.h>
#include <eh.h>
void SEFunc();
void trans_func( unsigned int, EXCEPTION_POINTERS* );
class SE_Exception
{
private:
    unsigned int nSE;
public:
    SE_Exception() {}
    SE_Exception( unsigned int n ) : nSE( n ) {}
    ~SE_Exception() {}
    unsigned int getSeNumber() { return nSE; }
};
int main( void )
{
    try
    {
        _set_se_translator( trans_func );
        SEFunc();
    }
    catch( SE_Exception e )
    {
        printf( "Caught a __try exception with SE_Exception.\n" );
    }
}
void SEFunc()
{
    __try
    {
        int x, y=0;
        x = 5 / y;
    }
    __finally
    {
        printf( "In finally\n" );
    }
}
void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
{
    printf( "In trans_func.\n" );
    throw SE_Exception();
}

答案 1 :(得分:1)

随机崩溃通常由堆损坏引起,很难找到。过去几年我遇到了几个堆腐败问题,正如我记得的那样,其中一个问题花了整整一个周的时间来追踪它。以下是一些建议:

  1. 首先尝试使用app验证程序。详情请见: http://msdn.microsoft.com/en-us/library/windows/desktop/dd371695(v=vs.85).aspx
  2. GFLAGS: http://msdn.microsoft.com/en-us/library/windows/hardware/ff549557(v=vs.85).aspx。 用它来启用页面堆验证。
  3. 解决方案1和2都使用堆验证 程序,所以你可能会得到许多例外并减慢你的程序, 但其中一些与你的问题无关。如果你知道哪个 部分代码有错误,可以使用窗口API _CrtSetDbgFlag来 启用堆验证,有点像这样:

    `int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);

    tmpFlag | = _CRTDBG_CHECK_ALWAYS_DF;

    _CrtSetDbgFlag(tmpFlag); //在alloc和dealloc

    时验证堆

    //你在这里编码,如果堆坏了,下次分配时会抛出异常。

    tmpFlag | = ~_CRTDBG_CHECK_ALWAYS_DF;

    _CrtSetDbgFlag(tmpFlag)//不要验证堆`

相关问题