|  | 
 
| SEGV问题,即内存访问违例。我使用ace 5.7构造的程序,其配置文件为 
 ----------------------------启动配置文件xxx.init--------------------------
 
 stream dynamic ProtocolStream STREAM *ProtocolStack:_make_ProtocolStream()
 {
 dynamic Translator Module *ProtocolModule_Translator:alloc()
 dynamic Filter Module *ProtocolModule_Filter:alloc()
 dynamic Compressor Module *ProtocolModule_Compress:alloc()
 dynamic Encryptor Module *ProtocolModule_Encrypt:alloc()
 }
 
 #业务处理模块
 dynamic LogonManager Service_Object *Svc_XXX1:_make_XXX1()
 dynamic LogonManager Service_Object *Svc_XXX2:_make_XXX2()
 dynamic LogonManager Service_Object *Svc_XXX3:_make_XXX3()
 dynamic LogonManager Service_Object *Svc_XXX4:_make_XXX4()
 dynamic LogonManager Service_Object *Svc_XXX5:_make_XXX5()
 .............
 
 -----------------------注销配置文件xxx.fini--------------------------------
 remove XXX5
 remove XXX4
 remove XXX3
 remove XXX2
 remove XXX1
 remove ProtocolStream
 
 ----------------------------------------------------
 
 服务加载没什么问题,关键是注销服务时,会出现内存访问违例故障。
 经过调试,发现问题在于ACE对于Module类型的服务处理不当,造成悬挂指针。
 
 
 解决方案:修改并重新编译ACE
 
 1、为了解决在解析svc.conf文件的remove stream时遇到的内存访问违例问题,可修改 Service_types.cpp 的ACE_Stream_Type::fini方法如下:
 int
 ACE_Stream_Type::fini (void) const
 {
 ACE_TRACE ("ACE_Stream_Type::fini");
 void *obj = this->object ();
 MT_Stream *str = (MT_Stream *) obj;
 for (ACE_Module_Type *m = this->head_; m != 0; )
 {
 ACE_Module_Type *t = m->link ();
 // Final arg is an indication to *not* delete the Module.
 str->remove (m->name (),
 MT_Module::M_DELETE_NONE);
 // Finalize the Module (this may delete it, but we don't really
 // care since we don't access it again).
 
 //注释掉下行
 //m->fini ();
 //替换为下行
 ACE_Service_Repository::instance()->remove(m->name());
 m = t;
 }
 str->close ();
 return ACE_Service_Type_Impl::fini ();
 }
 2、为了解决ACE::Fini时Service_Repository的内存访问违例问题,修改 Service_Repository.cpp 的 ACE_Service_Repository::fini 方法如下:
 int
 ACE_Service_Repository::fini (void)
 {
 ACE_TRACE ("ACE_Service_Repository::fini");
 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
 int retval = 0;
 // Do not be tempted to use the prefix decrement operator.  Use
 // postfix decrement operator since the index is unsigned and may
 // wrap around the 0
 for (size_t i = this->service_array_.size(); i-- != 0; )
 {
 // <fini> the services in reverse order.
 ACE_Service_Type *s =
 const_cast<ACE_Service_Type *> (this->service_array_);
 #ifndef ACE_NLOGGING
 if (ACE::debug ())
 {
 if (s != 0)
 ACE_DEBUG ((LM_DEBUG,
 ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ")
 ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"),
 this,
 i,
 s->name(),
 s->type (),
 (s->type () != 0) ? s->type ()->object () : 0,
 s->active ()));
 else
 ACE_DEBUG ((LM_DEBUG,
 ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"),
 this,
 i));
 }
 #endif
 // Collect any errors.
 if (s != 0 && s->type()->type()!=ACE_Service_Type::MODULE)  //zjw 2009.8.6 添加" && s->type()->type()!=ACE_Service_Type::MODULE"
 retval += s->fini ();
 }
 return (retval == 0) ? 0 : -1;
 }
 当然,为了配合上述代码,应为ACE_Service_Type_Impl类添加了一个虚函数type()来返回继承类的类型
 
 class ACE_Export ACE_Service_Type_Impl
 {
 ........
 public:
 //子类型提示
 virtual int type() const = 0;
 ........
 };
 
 class ACE_Export ACE_Service_Object_Type : public ACE_Service_Type_Impl
 {
 ........
 public:
 virtual int type() const
 {
 return ACE_Service_Type::SERVICE_OBJECT;
 }
 ........
 };
 
 
 class ACE_Export ACE_Module_Type : public ACE_Service_Type_Impl
 {
 ............
 public:
 virtual int type() const
 {
 return ACE_Service_Type::MODULE;
 }
 ...........
 };
 class ACE_Export ACE_Stream_Type : public ACE_Service_Type_Impl
 {
 ...........
 public:
 virtual int type() const
 {
 return ACE_Service_Type::STREAM;
 }
 ..........
 };
 | 
 |