Please report new issues athttps://github.com/DOCGroup
Created attachment 1423 [details] test example, that reproduced this bug PROBLEM-REPORT-FORM: TAO VERSION: 2.0.5 ACE VERSION: 6.0.5 HOST MACHINE and OPERATING SYSTEM: Windows 7 x64 Windows Socket 2.0 32 bit - 6.1.7600.16385 COMPILER NAME AND VERSION (AND PATCHLEVEL): Visual Studio 2009 SP1: 9.0.30729.1 THE $ACE_ROOT/ace/config.h FILE: #define ACE_HAS_STANDARD_CPP_LIBRARY 1 #include "ace/config-win32.h" THE $ACE_ROOT/include/makeinclude/platform_macros.GNU FILE: none CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/default.features (used by MPC when you generate your own makefiles): none AREA/CLASS/EXAMPLE AFFECTED: In attach DOES THE PROBLEM AFFECT: COMPILATION? no LINKING? no EXECUTION? yes OTHER (please specify)? crash SYNOPSIS: An application with integrated notification service (TAO_Notify_Service) crashes with error "access violation" during POA deactivation. Cause: premature deletion of POA, in which EventChannelFactory is activated. DESCRIPTION: Error is reproduced by the next steps (test example is in attachment): Initialization: 1. Init and start ORB 2. Integrate notification service into application using TAO_Notify_Service::load_default () 3. Create the Event Channel Factory Stopping: (do not call NotifyExt::EventChannelFactory::destroy, because it is not specified by CORBA standard ) 4. Unload notification service using finalize_service() and fini() 5. Explicitly deactivate POA Manager using deactivate( true, true ) Crash: 6. During POA Manager deactivation the application crashes with error "access violation", due to access attempt to destroyed POA. Description of crash dump. Crash dump stack: TAO_PortableServerd.dll!TAO::Portable_Server::Active_Policy_Strategies::servant_retention_strategy() Line 57 + 0x3 bytes C++ TAO_PortableServerd.dll!TAO_Root_POA::unbind_using_user_id(const CORBA::OctetSeq & user_id={...}) Line 1484 + 0xe bytes C++ > TAO_PortableServerd.dll!TAO::Portable_Server::RequestProcessingStrategyAOMOnly::cleanup_servant(TAO_ServantBase * servant=0x023d6f18, const CORBA::OctetSeq & user_id={...}) Line 121 + 0xf bytes C++ TAO_PortableServerd.dll!TAO_Root_POA::cleanup_servant(TAO_ServantBase * servant=0x023d6f18, const CORBA::OctetSeq & user_id={...}) Line 1493 + 0x28 bytes C++ TAO_PortableServerd.dll!TAO::Portable_Server::ServantRetentionStrategyRetain::deactivate_map_entry(TAO_Active_Object_Map_Entry * active_object_map_entry=0x023d7878) Line 111 C++ TAO_PortableServerd.dll!TAO::Portable_Server::ServantRetentionStrategyRetain::deactivate_all_objects() Line 485 C++ TAO_PortableServerd.dll!TAO_Root_POA::deactivate_all_objects_i(bool etherealize_objects=true) Line 1257 + 0x23 bytes C++ TAO_PortableServerd.dll!TAO_Root_POA::deactivate_all_objects_i(bool etherealize_objects=true, bool wait_for_completion=true) Line 1194 C++ TAO_PortableServerd.dll!TAO_POA_Manager::deactivate_i(bool etherealize_objects=true, bool wait_for_completion=true) Line 145 C++ TAO_PortableServerd.dll!TAO_POA_Manager::deactivate(bool etherealize_objects=true, bool wait_for_completion=true) Line 53 C++ Error occurs in method RequestProcessingStrategyAOMOnly::cleanup_servant: void RequestProcessingStrategyAOMOnly::cleanup_servant ( PortableServer::Servant servant, const PortableServer::ObjectId &user_id) { if (servant) { // ATTENTION: Trick locking here, see class header for details Non_Servant_Upcall non_servant_upcall (*this->poa_); ACE_UNUSED_ARG (non_servant_upcall); try { servant->_remove_ref (); } catch (...) { // Ignore exceptions from servant cleanup. } } // This operation causes the association of the Object Id specified // by the oid parameter and its servant to be removed from the // Active Object Map. if (this->poa_->unbind_using_user_id (user_id) != 0) { throw ::CORBA::OBJ_ADAPTER (); } } Call of servant->_remove_ref (); destroys Event Channel Factory servant. Destructor of Event Channel Factory destroys poa_, it leads to access violation in if (this->poa_->unbind_using_user_id (user_id) != 0) REPEAT BY: in attachment SAMPLE FIX/WORKAROUND: FIX. Examine whether it is right that destructor of servant destroys POA. In this case it is the destructor of the base class of Event Channel Factory: TAO_Notify_Object::~TAO_Notify_Object () { if (TAO_debug_level > 2 ) ACE_DEBUG ((LM_DEBUG,"object:%x destroyed\n", this )); this->destroy_proxy_poa (); this->destroy_object_poa (); this->destroy_poa (); } If it is not right, then it is necessary to revise the interaction of TAO_Notify_Service with POA. WORKAROUND. Before POA deactivation explicitly destroy Event Channel Factory using TAO-specific interface: NotifyExt::EventChannelFactory_var eventChannelFactoryExt = NotifyExt::EventChannelFactory::_narrow( eventChannelFactory_ ); eventChannelFactoryExt->destroy();
Proposal to extend destructor of servant to destroy POA is not a good solution.
I would like to clarify: The code from SAMPLE FIX is a copy of the current TAO's code. That is, in the current version of TAO Notification Service the POA is destroyed by servant destructor. I agree - it's not a good solution. Furthermore, the methods destroy_proxy_poa, destroy_proxy_poa, destroy_poa are not specified by CORBA specification. My proposal: refine code and eliminate this methods. Are there any ideas, why this code (destroying POA in servant destructor) has been added? I do not understand this yet. Thanks.