Я провел некоторые поиски здесь, в MSDN, и через некоторые другие форумы через Google, пытаясь найти какое-либо решение для этого, но до сих пор застрял.
Я искал неделю, пытаясь отследить ошибку нарушения доступа в моей программе C ++. Я действительно не могу разместить код здесь, так как он находится под некоторыми ограничениями IP, но в основном это цикл, который выполняется примерно каждые 100 мс, считывая байты из TCP-соединения и помещая их в конец std :: queue.
После того, как я заметил, что определенная последовательность байтов прошла, я удаляю x байтов из очереди и обрабатываю их как сообщение, определенное во внутреннем протоколе.
Что происходит, где-то внутри моего приложения, очередь становится поврежденной и вылетает приложение. Так соедините это с фактом, что это — нарушение доступа, это должен быть хитрый указатель где-нибудь.
Я попытался использовать отладчик VS2005 и Windbg, чтобы найти его, мне пришлось посмотреть стеки вызовов, но это не сильно помогло. Все, что я мог понять из этого, — то, что причина — повреждение моей внутренней очереди. Причина сбоя заключается в том, что заголовок сообщения отправляется на анализ, а потому что он поврежден, все падает.
Затем я попробовал Intel Thread Checker, но он слишком медленный, чтобы использовать его в этом приложении, поскольку моя программа является частью синхронной многопоточной системы.
Иногда он будет работать на 300 операций чтения … иногда он может делать 5000 операций чтения … иногда он может делать 10000 операций чтения до сбоя.
Какие еще способы диагностики я могу попробовать? Мне не хватает чего-то простого, что я уже должен был проверить? Из того, что я вижу, все, что обновляется, имеет соответствующее удаление, и я использую Boost-библиотеки для общих указателей и авто-указателей на долгоживущих объектах.
Используйте SEH (структурированная обработка исключений), чтобы узнать, какая часть вызывает AV.
#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 и 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) // не проверять кучу