c++コードがリリースモードでコンパイルされている場合にのみ発生するある種のメモリまたはwinsockの問題があります。
そのメモリの問題の証拠:
以前の未知のバグは、2行のコードをコメントアウトすることで修正されました。これらの2行のコードは無害に見えます。それらは古いバージョンから残されました。これは、どこかで初期化されていないメモリを使用していることを示しています。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とcrossroads/0mqの両方を使用している場合にのみ発生します。また、デバッガーで処理を開始してもバグは発生しません。
したがって、「realesewithdebuginfo」モードでコンパイルすると、デバッガーにない場合にのみバグが発生します。同じ正確にコンパイルされたコード。
質問1:C++コード分析やWindowsAPI呼び出し分析に推奨されるツールは何ですか?また、問題は簡単に再現できないため、静的分析が最適な場合があります。私はたくさんのテンプレート、boost :: asio :: udp、複数のトレッドライブラリを使用しています。複数のsocket/ioライブラリ。
質問2:外部ライブラリによるソケットの誤用が原因でデッドロックが発生しているかどうかを確認するために、Windows側で何を利用できますか?
tyvm4yh