Память. Какие полезные советы можно отследить, когда C0000005 нарушает доступ в C ++?

Я провел некоторые поиски здесь, в MSDN, и через некоторые другие форумы через Google, пытаясь найти какое-либо решение для этого, но до сих пор застрял.

Я искал неделю, пытаясь отследить ошибку нарушения доступа в моей программе C ++. Я действительно не могу разместить код здесь, так как он находится под некоторыми ограничениями IP, но в основном это цикл, который выполняется примерно каждые 100 мс, считывая байты из TCP-соединения и помещая их в конец std :: queue.

После того, как я заметил, что определенная последовательность байтов прошла, я удаляю x байтов из очереди и обрабатываю их как сообщение, определенное во внутреннем протоколе.

Что происходит, где-то внутри моего приложения, очередь становится поврежденной и вылетает приложение. Так соедините это с фактом, что это — нарушение доступа, это должен быть хитрый указатель где-нибудь.

Я попытался использовать отладчик VS2005 и Windbg, чтобы найти его, мне пришлось посмотреть стеки вызовов, но это не сильно помогло. Все, что я мог понять из этого, — то, что причина — повреждение моей внутренней очереди. Причина сбоя заключается в том, что заголовок сообщения отправляется на анализ, а потому что он поврежден, все падает.

Затем я попробовал Intel Thread Checker, но он слишком медленный, чтобы использовать его в этом приложении, поскольку моя программа является частью синхронной многопоточной системы.

Иногда он будет работать на 300 операций чтения … иногда он может делать 5000 операций чтения … иногда он может делать 10000 операций чтения до сбоя.

Какие еще способы диагностики я могу попробовать? Мне не хватает чего-то простого, что я уже должен был проверить? Из того, что я вижу, все, что обновляется, имеет соответствующее удаление, и я использую Boost-библиотеки для общих указателей и авто-указателей на долгоживущих объектах.

2

Решение

Используйте SEH (структурированная обработка исключений), чтобы узнать, какая часть вызывает AV.

SEH в C ++ пример кода из MSDN.

#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();
}
3

Другие решения

Случайный сбой, обычно вызванный повреждением кучи, найти сложно. В прошлые годы у меня было несколько проблем с кучей коррупции, и, как я помню, одна из проблем заняла у меня целые выходные, чтобы выследить ее. Вот несколько предложений:

  1. Сначала попробуйте проверить приложение. Подробности в:
    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) // не проверять кучу

1