gcc 4.1, 下面是代码内容:
// 这是main函数当中的调用语句
CProxy proxy(argv[1]);
// 这里是proxy的构造函数
CProxy::CProxy(const char*filename)
{
ifstream input;
string ip;
string port;
inu32 destid;
input.open(filename, ios::in);
input >> proxyid;
while (true)
{
input >> ip;
if (input.eof() || ip == "END_OF_CONNECTION")
{
break;
}
input >> port;
S_MsgHead regist;
S_MsgHead response;
regist.cmd = msg_proxy_gamelogic_register;
response.cmd = msg_gamelogic_proxy_response;
input >> destid;
response.res = destid;
// 程序执行到这条语句发生了段错误,其中ioOwn是该类的成员变量。
new CCconnect(&ioOwn, ip, port, this, regist,response));
}
}
// 这里是CCconnect的构造函数。
// 我们跟踪进入 m_socket之后发生了段错误,如问题描述当中所示。
CCconnect::CCconnect
( boost::asio::io_service* pio , std::string host , std::string port , CInterfaceHandler* ph ,S_MsgHead msg_register ,S_MsgHead msg_response)
:m_socket(*pio) ,m_pio_service_own(pio),m_lRecv( 0 ),m_pHandler(ph)
,m_inum_reconnect(0)
,m_flag_connect (-1)
,m_timer_connect( *pio )
,m_is_informed(-1)
{
cout << “cconnect construct” << endl;// 这条语句没有被打印
memset( &m_oMsgHead, 0, sizeof( m_oMsgHead ) );
memset( m_szRecv, 0, sizeof( m_szRecv ) );
m_strRecv = "";
m_strhost = host ;
m_strport = port ;
m_oMsg_register = msg_register;
m_oMsg_response = msg_response;
}
makefile文件内容:
# compiler
c++ := c++
# options
c++flags := -I/home/nebuladream/boost_1_39_0 -g -c
# source code path
src_path := ./
#lib_path := /usr/local/lib/
lib_path := /home/nebuladream/boost_1_39_0/stage/lib/
# run
run := $(c++) $(c++flags)
#$(cc) $(cflags) $^ -o $@
proxy : main.o accept.o proxy.o cconnect.o sconnect.o \
$(lib_path)libboost_system-gcc41-mt-d-1_39.a $(lib_path)libboost_thread-gcc41-mt-d-1_39.a \
$(lib_path)libboost_python-gcc41-mt-d-1_39.a
$(c++) -g -o $@ $^ -lpthread
main.o : main.cpp
$(run) $^
accept.o : $(src_path)accept.cpp
$(run) $^
proxy.o : $(src_path)proxy.cpp
$(run) $^
sconnect.o : $(src_path)sconnect.cpp
$(run) $^
cconnect.o : $(src_path)cconnect.cpp
$(run) $^
clean :
rm main.o accept.o proxy.o cconnect.o sconnect.o proxy
cleantemp :
rm main.o accept.o proxy.o cconnect.o sconnect.o
address-model=64, and the instruction-set
feature should refer to a 64 bit processor. Currently, those
include nocona, opteron,
athlon64 and athlon-fx.
直接在main里调用 new CConnect(xxx), 会发生什么?
CProxy 有没有基类?有哪些成员?类型是什么?
CConnect 有没有基类?有哪些成员?类型是什么?
一点一点挤牙膏....
第 208 行以 && 开头,并不完整,前面估计就有 service.type_info_ != 0。
LZ 给的上下文太少了。
On Oct 24, 7:33 pm, Fei Yan <skyscribe...@gmail.com> wrote:
> 查了一下1.40的代码,发现这个地方的代码已经有所改动,主要是加了指针检查:
> 200 #if !defined(BOOST_ASIO_NO_TYPEID)
> 201 // Check if a service matches the given id.
> 202 template <typename Service>
> 203 static bool service_id_matches(
> 204 const boost::asio::io_service::service& service,
> 205 const boost::asio::detail::service_id<Service>& /*id*/)
> 206 {
> *207 return service.type_info_ != 0
> 208 && *service.type_info_ == typeid(typeid_wrapper<Service>);*
> 209 }
> 你不妨参照新版本的检查,在你最后一个地方加一个breakpoint,然后查看service.type_info_对应的地址是否是合法的64位地址;你的segment
> fault应该是由于指针解引用引起的,而这个地址的初始化是在这里(会在service构造的时候调用):
> 183 template <typename Service>
> 184 void init_service_id(boost::asio::io_service::service& service,
> 185 const boost::asio::detail::service_id<Service>& /*id*/)
> 186 {
> *187 service.type_info_ = &typeid(typeid_wrapper<Service>);*
> 188 service.id_ = 0;
> 189 }
>
> 那个wrapper类则是个很简单的空模板类,用于RTTI标示ID的(不同的模板参数会生成不同的类,从而对应的typeid也不一样):
> 46 template <typename T>
> * 47 class typeid_wrapper {};
>
> *我手头没有1.39的代码,不过对应部分应该差不多,你不妨在前两个标记的地方设置breakpoints查查看*
> *
感谢大家的留言,我也在一直在着手解决上述的问题。这几天我写了一些相关的代码来验证我的想法,又发现了如下诡异的问题。我在四楼贴出的那段段代码,如果在CProxy类的声明当作加入一个socket对象的声明,我发现上述代码将不会在CConnect类初始化列表当中发生段错误,但是程序会在接下来的主动连接代码中发生问题。
boost::asio::ip::tcp::resolver resolver( *m_pio_service_own );
boost::asio::ip::tcp::resolver::query query( m_strhost, m_strport );
boost::asio::ip::tcp::resolver::iterator endpoint_iterator= resolver.resolve(query);
// 非常奇怪,在iterator初始化过程当中将会产生段错误。
boost::asio::ip::tcp::resolver::iterator end;
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
m_socket.close();
m_socket.connect(*endpoint_iterator++, error);
}
我又尝试着写出如下代码,试图发现产生段错误原因,但是奇怪的是下面这段代码却可以正常的运行通过!可以说下面程序的基本结构已经与我的程序及其相似了。只是网络层并没有我的程序那么复杂(而出问题的那段代码与下面这段代码唯一的不同就是初始化列表当作多加入了几个初始化成员变量)。之后,我将test换成调用问题代码的CConnect,就会在前面所说的
// 非常奇怪,在iterator初始化过程当中将会产生段错误。
boost::asio::ip::tcp::resolver::iterator end;
地方发生段错误!!!
如果本周这个问题还是不能解决,我已经开始考虑重写代码了……这件事告诉我以后开发时候还是使用64位系统比较稳妥,发现问题可以及时找到。
//main.cpp
#include "test.h"
int main()
{
test t;
t.run();
return 0;
}
//test.h
#ifndef TEST_H
#define TEST_H
#endif
#include "cconnect.h"
#include "interfacehandler.h"
#include <boost/thread.hpp>
#include <string>
#include <iostream>
#include <vector>
using namespace std;
// CInterfaceConnect是网络层抽象的接口。
typedef boost::shared_ptr<CInterfaceConnect> pIConnect;
// CinterfaceHandler是数据包处理层的抽象接口。
class test : public CInterfaceHandler
{
private:
boost::asio::io_service ioOwn;
vector< boost::shared_ptr< boost::thread > > m_vt_Thread;
public:
~test(){}
test();
void run();
boost::asio::io_service* get_pio( void ){return &ioOwn;}
void handle( std::string sdata ,pIConnect pcon );
};
// test.cpp
#include "test.h"
#include "timer.h"
test::test()
{
pIConnect pconnect(new CCconnect( &ioOwn , "192.168.1.77" , "80" , this ) );
pconnect->run();
}
void test::run()
{
new CTimer( ioOwn );
for( size_t x = 0 ; x < 5 ; ++ x )
{
boost::shared_ptr< boost::thread > pnewown( new boost::thread( boost::bind( &boost::asio::io_service::run, &ioOwn ) ) );
m_vt_Thread.push_back( pnewown );
}
std::cout << "process run ... " << std::endl;
for( size_t y = 0 ; y < m_vt_Thread.size() ; ++ y )
m_vt_Thread[ y ]->join();
}
void test::handle( std::string sdata ,pIConnect pcon )
{
cout << "handle function." << endl;
}
// CConnect.cpp代码
#include "cconnect.h"
// 这个构造函数仅仅比出问题的构造函数少了几个初始化变量,而这几个初始化变量全部都是int类型
CCconnect::CCconnect(boost::asio::io_service* pio , std::string h , std::string p , CInterfaceHandler* ph ):pioOwn(pio), m_pHandler(ph),m_socket(*pio)
{
host = h ;
port = p ;
}
void CCconnect::run( void )
{
Connect();
}
// 这一段是主动连接服务器的程序。boost库的example中就是这么写的。
void CCconnect::Connect( void )
{
cout << "connect." << endl;
boost::asio::ip::tcp::resolver resolver( *pioOwn );
boost::asio::ip::tcp::resolver::query query( host, port );
boost::asio::ip::tcp::resolver::iterator endpoint_iterator= resolver.resolve(query);
boost::asio::ip::tcp::resolver::iterator end;
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
m_socket.close();
m_socket.connect(*endpoint_iterator++, error);
}
if (error)
{
#ifdef _DEBUG_DISPLAY_
std::cout << "------CConnect:error" << std::endl;
#endif
Connect() ;
}
else
{
#ifdef _DEBUG_DISPLAY_
std::cout << "------Cconnect:start to send register package" << std::endl;
#endif
Send_RegisterMsg() ;
}
}
void CCconnect:: Send_RegisterMsg()
{
try
{
#ifdef _DEBUG_DISPLAY_
std::cout << "------CCconnect:: Send_RegisterMsg() " << std::endl;
#endif
boost::asio::async_write( m_socket, boost::asio::buffer( buffer , sizeof(1024) ),
boost::bind( &CCconnect::Receive, shared_from_this(), boost::asio::placeholders::error ) );
}
catch (exception& e)
{
std::cerr<< "CCconnect:: Send_RegisterMsg() :"<< e.what() ;
}
catch (...)
{
std::cerr << "CCconnect:: Send_RegisterMsg : oh no \n" ;
}
}
void CCconnect::Receive(const boost::system::error_code& error)
{
Recv_MsgHead();
}
void CCconnect::Recv_MsgHead( void )
{
#ifdef _DEBUG_DISPLAY_
std::cout << "------CCconnect:: Recv_MsgHead" << std::endl;
#endif
boost::asio::async_read( m_socket, boost::asio::buffer( buffer, 1000 ),
boost::asio::transfer_at_least( 1 ),
boost::bind( &CCconnect::Recv_MsgHead_End, shared_from_this(),boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred ) );
}
void CCconnect::Recv_MsgHead_End( const boost::system::error_code& error, std::size_t bytes_transferred )
{
string data = buffer;
( m_pHandler->get_pio() )->post( boost::bind ( &CInterfaceHandler::handle, m_pHandler, data, shared_from_this() ) ) ;
Recv_MsgHead();
}
On 10月30日, 上午2时14分, Fuzhou Chen <cppof...@gmail.com> wrote:
> 因为公司的限制我不能看boost的代码。所以只能从这个trace考虑:
On 10月30日, 上午11时16分, Fuzhou Chen <cppof...@gmail.com> wrote:
> 恰恰是因为授权松所以无法看。我和公司签的合同要求我不得看任何open source的代码,所以我也没法帮上太多。
>
> 2009/10/29 pi1ot <pilot...@gmail.com>
那岂不是小心翼翼防不胜防,不小心打开个网页都能看到open source的js代码。
On 10月30日, 上午11时16分, Fuzhou Chen <cppof...@gmail.com> wrote:
> 恰恰是因为授权松所以无法看。我和公司签的合同要求我不得看任何open source的代码,所以我也没法帮上太多。
>
On Oct 31, 1:37 am, Fuzhou Chen <cppof...@gmail.com> wrote:
> 严格地说的确是非工作时间也不能看,看了的话一旦被发现就被解雇了。补偿金不太可能,我们同事间的笑话是让您到这儿来干活已经是恩典了,这么牛的code都看不够,还看什么Open
> Source,总而言之,这是政治问题不是技术问题,呵呵。
>
> 所以自从被招安之后俺就再也没敢到kernel.org下内核了。
>
> P.S.:跑题了......
>
> 2009/10/30 up duan <fixo...@gmail.com>
>
>
>
> > 2009/10/30 pi1ot <pilot...@gmail.com>
GCC可以靠aligned和packed属性对单个变量指定对齐。http://tigcc.ticalc.org/doc/gnuexts.html#SEC91_aligned,印象里倒是没有命令行选项要求对齐变量的。虽然有-falign-functions之类的,但只针对语句块,主要用于代码段的优化。我的观点是字节对齐这种东西太冒险,说不好什么时候就出问题。