在编译发布时使用什么工具来查找c++错误.助推::阿西奥,cmake.vs2012.十字路口/0mq

what tools to use to find c++ bug when compile for release. boost::asio, cmake. vs2012. crossroads / 0mq

本文关键字:cmake 0mq 十字路口 vs2012 助推 错误 布时使 编译 什么 工具 c++      更新时间:2023-10-16

我遇到了某种内存或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()
{
}

};

这是一个窗口/套接字问题的证据:

真正的错误是我的tcp套接字(localhost)从不获取数据。然而,只有当我在同一个过程中同时使用boost::asio和crosstol/0mq时,才会发生这种情况。此外,如果我通过调试器启动进程,则不会出现错误。

因此,当我在"realesewithdebuginfo"模式下编译时,只有当不在调试器中时才会出现错误。完全相同的编译代码。

问题1:推荐使用什么工具进行c++代码分析和/或windowsapi调用分析?此外,这个问题不容易重现,所以静态分析可能是最好的。我使用了很多模板,boost::asio::udp,多个线程库。多个socket/io库。

问题2:在windows端,有什么可以查看我是否由于外部库的套接字I/o错误导致死锁?

tyvm4yh

在调试器下运行与不在调试器下执行的主要区别在于调试堆。要关闭调试堆,可以使用_NO_DEBUG_HEAP环境变量。你可以在全局范围内设置它,但你最好只为调试运行而这样做,如下所示:

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

如果这重现了错误,但您在实际调试中遇到了困难(因为优化了代码),我只会暂时禁用您版本的优化。只是别忘了再次打开它们。。。

几乎每次,关闭调试堆并禁用优化都会让我在调试器中重现这种错误,然后调试它,而不会有太多麻烦。

此外,如果你使用Windows7,你可能会发现程序兼容性助手正在介入并做一些让你的程序正常工作的事情,即使它不应该:

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/

如果您在调试器之外运行程序,强烈建议禁用程序兼容性助手。。。