Visual Studio — какие инструменты использовать, чтобы найти ошибку C ++ при компиляции для выпуска. boost :: asio, cmake. vs2012. перекресток / 0mq

У меня есть проблема с памятью или winsock, которая возникает, только когда код c ++ скомпилирован в режиме выпуска.

Доказательства того, что это проблема с памятью:

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

        class XS_Client
{
private:

/* these two lines of comments fixed the bug */
/***********************************************
enum { max_length = 1024 };
char data_[max_length];
**********************************************/

void * context_;
void * socket_;
boost::thread t_;
volatile bool should_run_;
public:
XS_Client(void *context, short type, const std::string &address)
: context_(context), socket_(XS_Socket::NewSocket(context_,type))
{
XS_Socket::Connect(socket_,address);
#ifdef _OUTPUTD
std::cout << address << " XS_Client: " << GetCurrentThreadId() << std::endl;
#endif
boost::thread   t(boost::bind(&XS_Client::thread_func, this));
t_.swap(t);
}

void SetSockOpt(int option, const void *optval,size_t optvallen)
{
int rc = xs_setsockopt(socket_,option,optval,optvallen);
if ( rc != 0 )
std::cout << "xs_setsockopt error: " << xs_strerror(errno) << std::endl;
}

virtual ~XS_Client()
{
if ( should_run_ )
Stop();
}

void thread_func() {
/* Create an empty message */
xs_msg_t msg;

while (should_run_)
{
//int bytes_recvd = xs_recv(socket_,data_,max_length,0);
int rc = xs_msg_init (&msg);
if ( rc != 0 )
std::cout << "xs_msg_init error: " << xs_strerror(errno) << std::endl;
assert (rc == 0);
/* Block until a message is available to be received from socket */
int bytes_recvd = xs_recvmsg (socket_, &msg, 0);

#ifdef _DEBUG
std::cout << "received " << bytes_recvd << std::endl;
#endif;

if ( bytes_recvd == -1 )
{

if ( xs_errno() == ETERM )
{
should_run_ = false;
std::cout << "ETERM received" << xs_strerror(errno) << std::endl;
break;
}

if ( !should_run_ )
xs_msg_close (&msg);
else
{
std::cout << "receive error!" << xs_strerror(errno) << std::endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(100u));
}
}
else
{

#ifdef _DEBUG
//std::cout << "received " << xs_msg_data(&msg) << std::endl;
#endif;
OnMsg(xs_msg_data(&msg),bytes_recvd);

/* Release message */
xs_msg_close (&msg);
}

}

int rc = xs_close (socket_);
if ( rc != 0 )
std::cout << "xs_close error: " << xs_strerror(errno) << std::endl;

Cleanup();
}

virtual void OnMsg(const void *msg, int bytes_recvd)
{
std::cout << "virtual void OnMsg received " << bytes_recvd << std::endl;
}

virtual void Stop()
{
should_run_ = false;
t_.timed_join(boost::posix_time::milliseconds(2000));
}

virtual void Cleanup()
{
}};

Доказательство того, что проблема с Windows / сокетом:

Настоящая ошибка в том, что мой сокет tcp (localhost) никогда не получает данные. Однако это происходит только тогда, когда я использую оба boost :: asio и crossroads / 0mq в одном процессе. Также ошибка не возникает, если я запускаю процесс через отладчик.

Поэтому, когда я компилирую в режиме «realesewithdebuginfo», ошибка возникает, только когда нет в отладчике. точно такой же скомпилированный код.

вопрос1: какой инструмент рекомендуется для анализа кода c ++ и / или анализа вызовов API Windows? Кроме того, проблему нелегко воссоздать, поэтому лучше всего использовать статический анализ. Я использую много шаблонов, boost :: asio :: udp, несколько протекторных библиотек. несколько библиотек сокетов / IO.

вопрос2: что доступно на стороне Windows, чтобы увидеть, вызывает ли я тупик из-за неправильного использования сокетов ввода-вывода внешними библиотеками?

tyvm4yh

1

Решение

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

https://stackoverflow.com/a/1060929/1618406

Если это воспроизводит ошибку, но у вас возникают трудности с отладкой (из-за оптимизированного кода), я бы просто временно отключил оптимизацию для вашей сборки выпуска. Только не забудьте снова включить их …

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

Кроме того, если вы используете Windows 7, вы можете обнаружить, что помощник по совместимости программ вмешивается и делает что-то, что заставляет вашу программу работать, даже если это не так:

http://www.virtualdub.org/blog/pivot/entry.php?id=319

Якобы вы можете отключить это в манифесте вашей программы, но я предпочитаю отключить его с помощью редактора групповой политики, например:

http://www.howtogeek.com/howto/4161/disable-program-compatibility-assistant-in-windows-7-and-vista/

Настоятельно рекомендуется отключить Помощник по совместимости программ, если вы когда-либо запускали свою программу вне отладчика …

2

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

Других решений пока нет …

По вопросам рекламы [email protected]