[tao-bugs] [ft_naming service] adding member to object group fails (FT_Naming::NamingManager add_member throws exception ObjectNotAdded)

kirill grishko kyrylogryshko at gmail.com
Sun Apr 24 16:40:00 CDT 2016


    TAO VERSION: 2.2.6
    ACE VERSION: 6.2.6

    HOST MACHINE and OPERATING SYSTEM:
        Windows XP 32 bit,  winsock: ws2_32.dll version 5.1.2600.5512
        problem was also reproduced with tao 2.2.1 on Windows Server 2012
R2 64bit.
        Source comparison shows that the problem should exist in the latest
version (2.3.3) as well.


    COMPILER NAME AND VERSION (AND PATCHLEVEL):
        Microsoft visual studio 2010, service pack 1, 32 bit.

    THE $ACE_ROOT/ace/config.h FILE :
        #include "ace/config-win32.h"

    CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/default.features
    (used by MPC when you generate your own makefiles):
        (did not find such file)

    AREA/CLASS/EXAMPLE AFFECTED:
    FT_NAMING/NamingManager/ load balancing example

    Example fails to execute:
$ACE_ROOT/TAO/orbsvcs/tests/FT_Naming/Load_Balancing (server project)


    DOES THE PROBLEM AFFECT:
        EXECUTION

The problem affects TAO ft_naming service, when it is used with load
balancing (object groups) feature.
The problem affects tao sample (FT_Naming\load_balancing), and my custom
application that uses the same service.

    SYNOPSIS:
Call to FT_Naming::NamingManager's add_member method fails to add member to
group with exception PortableGroup::ObjectNotAdded.

    DESCRIPTION:
Server application that uses FT_Naming service with object groups receives
exception PortableGroup::ObjectNotAdded when adding first member to object
group by  call
to FT_Naming::NamingManager's add_member method.
NamingManager object (reference) was returned by
orb.resolve_initial_references("NamingManager") and narrowed by
FT_Naming::NamingManager::_narrow.
Object group was initially created with a call to create_object_group.

tao_ft_naming.exe shows the following output:
   TAO_FT_Naming_Manager::add_member - Issue with IOR of group or member.


    REPEAT BY:

0) build ft_naming load balancing sample from distribution:

ace_wrappers\TAO\orbsvcs\tests\ft_naming\Load_Balancing\Load_Balancing_vc10.sln
1) launch tao_ft_naming
2) launch server.exe  (built sample server)
( i launched tao_ft_naming service with specified endpoint, and then
provided that endpoint to server application.
tao_ft_naming  -ORBListenEndpoints iiop://localhost:9809 -d
server -ORBInitRef NameService=corbaloc:iiop:localhost:9809/NameService
-ORBInitRef NamingManager=corbaloc:iiop:localhost:9809/NamingManager
)
3) server fails to execute and  exits with error message
(1900|2896) EXCEPTION, Exception raised while registering servant
user exception, ID 'IDL:omg.org/PortableGroup/ObjectNotAdded:1.0'


   exception occurs while calling naming manager add_member method, it is
called from LB_server::register_servant.File lb_server.cpp, line 208.

   this->object_group_ =
        this->naming_manager_->add_member (this->object_group_.in (),
                                           location,
                                           basic.in ());



    SAMPLE FIX/WORKAROUND:


Real exception occurs in process tao_ft_naming, source file
IORManipulation.cpp (IORManipulation project),
method TAO_IOR_Manipulation_impl::merge_iors, line 70 (after comparing type
ids in merged iors).


IORManipulatuin.cpp

      // If the object type_id's differ then raise an exception.
      if (id.in () && iors[i]->_stubobj ()->type_id.in () &&
          ACE_OS::strcmp (id.in (), iors[i]->_stubobj ()->type_id.in ()))
          throw TAO_IOP::Invalid_IOR ();
//!!!!    ^^^^^^^^^^^^    exception is thrown in the previous line

The problem is that the only object in group after its creation is simply
corba object.
And when the new real object is added (iors are merged), type of the new
object is compared with corba object type (the first member). and the
exception is thrown because the types are different. (in fact they should
not be compared with corba object's type)
The first corba object does not have a profile at the moment of merging
iors.
So the solution can be in selecting type id to compare not from the first
object (ior), but from the first ior that has profile.

To solve the problem i removed lines 52, 53 (IORManipulation.cpp)

  CORBA::String_var id =
    CORBA::string_dup (iors[0]->_stubobj ()->type_id.in ());


and changed lines 34-37 from

  for (i = 0; i < iors.length (); i++)
    {
      count += iors[i]->_stubobj ()->base_profiles ().profile_count ();
    }

to the following (to set id to the type_id of the first ior with non zero
profile count)

  CORBA::String_var id;// type id to compare with

  for (i = 0; i < iors.length (); i++)
    {
      int n_profiles = iors[i]->_stubobj ()->base_profiles ().profile_count
();
      count += n_profiles;
      if (n_profiles && !id.in())
        id = CORBA::string_dup (iors[i]->_stubobj ()->type_id.in ());
    }

this code change solved the problem.
Perhaps we can also change the cycle that merges profiles to start with 0
index and to do merging only when profile count is not empty (but the
service works without this extended change, because in this situation
exactly the first ior has no profile).


real stack while debugging tao_ft_naming

    TAO_IORManipd.dll!TAO_IOR_Manipulation_impl::merge_iors(const
TAO_IOP::TAO_IOR_Manipulation::IORList & iors)  Line 72    C++

TAO_PortableGroupd.dll!TAO::PG_Object_Group_Manipulator::merge_iors(TAO_IOP::TAO_IOR_Manipulation::IORList
& list)  Line 130 + 0x29 bytes    C++

TAO_PortableGroupd.dll!TAO::PG_Object_Group::add_member_to_iogr(CORBA::Object
* member)  Line 207 + 0xf bytes    C++
     TAO_PortableGroupd.dll!TAO::PG_Object_Group::add_member(const
CosNaming::Name & the_location, CORBA::Object * member)  Line 269 + 0x13
bytes    C++

TAO_FT_Naming_Servd.dll!TAO_FT_Naming_Manager::add_member(CORBA::Object *
object_group, const CosNaming::Name & the_location, CORBA::Object *
member)  Line 433 + 0x17 bytes    C++

TAO_PortableGroupd.dll!POA_PortableGroup::add_member_ObjectGroupManager::execute()
Line 3099 + 0x23 bytes    C++
     TAO_PortableServerd.dll!TAO::Upcall_Wrapper::upcall(TAO_ServerRequest
& server_request, TAO::Argument * const * args, unsigned int nargs,
TAO::Upcall_Command & command, TAO::Portable_Server::Servant_Upcall *
servant_upcall, CORBA::TypeCode * const * exceptions, unsigned int
nexceptions)  Line 109 + 0xf bytes    C++

TAO_PortableGroupd.dll!POA_PortableGroup::ObjectGroupManager::add_member_skel(TAO_ServerRequest
& server_request, TAO::Portable_Server::Servant_Upcall * servant_upcall,
TAO_ServantBase * servant)  Line 3165 + 0x2a bytes    C++

TAO_PortableServerd.dll!TAO_ServantBase::synchronous_upcall_dispatch(TAO_ServerRequest
& req, TAO::Portable_Server::Servant_Upcall * servant_upcall,
TAO_ServantBase * derived_this)  Line 574 + 0x11 bytes    C++

TAO_FtNamingd.dll!POA_FT_Naming::NamingManager::_dispatch(TAO_ServerRequest
& req, TAO::Portable_Server::Servant_Upcall * servant_upcall)  Line 746 +
0x51 bytes    C++

TAO_PortableServerd.dll!TAO_Object_Adapter::do_dispatch(TAO_ServerRequest &
req, TAO::Portable_Server::Servant_Upcall & upcall)  Line 1198 + 0x4b
bytes    C++
     TAO_PortableServerd.dll!TAO_Object_Adapter::dispatch_servant(const
TAO::ObjectKey & key, TAO_ServerRequest & req,
TAO_Pseudo_Out_T<CORBA::Object> forward_to)  Line 353 + 0x1a bytes    C++
     TAO_PortableServerd.dll!TAO_Object_Adapter::dispatch(TAO::ObjectKey &
key, TAO_ServerRequest & request, TAO_Pseudo_Out_T<CORBA::Object>
forward_to)  Line 766 + 0x28 bytes    C++
     TAOd.dll!TAO_Adapter_Registry::dispatch(TAO::ObjectKey & key,
TAO_ServerRequest & request, TAO_Pseudo_Out_T<CORBA::Object> forward_to)
Line 110 + 0x33 bytes    C++
     TAOd.dll!TAO_Request_Dispatcher::dispatch(TAO_ORB_Core * orb_core,
TAO_ServerRequest & request, TAO_Pseudo_Out_T<CORBA::Object> forward_to)
Line 22    C++
     TAOd.dll!TAO_GIOP_Message_Base::process_request(TAO_Transport *
transport, TAO_InputCDR & cdr, TAO_OutputCDR & output,
TAO_GIOP_Message_Generator_Parser * parser)  Line 1018    C++
     TAOd.dll!TAO_GIOP_Message_Base::process_request_message(TAO_Transport
* transport, TAO_Queued_Data * qd)  Line 737 + 0x1e bytes    C++
     TAOd.dll!TAO_Transport::process_parsed_messages(TAO_Queued_Data * qd,
TAO_Resume_Handle & rh)  Line 2502 + 0x17 bytes    C++
     TAOd.dll!TAO_Transport::handle_input_parse_data(TAO_Resume_Handle &
rh, ACE_Time_Value * max_wait_time)  Line 2426 + 0x13 bytes    C++
     TAOd.dll!TAO_Transport::handle_input(TAO_Resume_Handle & rh,
ACE_Time_Value * max_wait_time)  Line 1760 + 0x10 bytes    C++
     TAOd.dll!TAO_Connection_Handler::handle_input_internal(void * h,
ACE_Event_Handler * eh)  Line 292 + 0x29 bytes    C++
     TAOd.dll!TAO_Connection_Handler::handle_input_eh(void * h,
ACE_Event_Handler * eh)  Line 251 + 0x10 bytes    C++
     TAOd.dll!TAO_IIOP_Connection_Handler::handle_input(void * h)  Line
408    C++
     ACEd.dll!ACE_TP_Reactor::dispatch_socket_event(ACE_EH_Dispatch_Info &
dispatch_info)  Line 545 + 0xe bytes    C++
     ACEd.dll!ACE_TP_Reactor::handle_socket_events(int & event_count,
ACE_TP_Token_Guard & guard)  Line 415 + 0xc bytes    C++
     ACEd.dll!ACE_TP_Reactor::dispatch_i(ACE_Time_Value * max_wait_time,
ACE_TP_Token_Guard & guard)  Line 244 + 0x10 bytes    C++
     ACEd.dll!ACE_TP_Reactor::handle_events(ACE_Time_Value *
max_wait_time)  Line 173 + 0x10 bytes    C++
     ACEd.dll!ACE_Reactor::handle_events(ACE_Time_Value * max_wait_time)
Line 188 + 0x27 bytes    C++
     TAOd.dll!TAO_ORB_Core::run(ACE_Time_Value * tv, int perform_work)
Line 2301 + 0xf bytes    C++
     TAOd.dll!CORBA::ORB::run(ACE_Time_Value * tv)  Line 189    C++
     TAOd.dll!CORBA::ORB::run()  Line 175    C++
     tao_ft_naming.exe!ORB_Runner::svc()  Line 133 + 0x15 bytes    C++
     tao_ft_naming.exe!TAO_FT_Naming_Service::run()  Line 155 + 0x8
bytes    C++
     tao_ft_naming.exe!ace_main_i(int argc, char * * argv)  Line 55    C++
     tao_ft_naming.exe!ACE_Main::run_i(int argc, char * * argv)  Line 40 +
0x30 bytes    C++
     ACEd.dll!ACE_Main_Base::run(int argc, char * * argv)  Line 88 + 0x17
bytes    C++
     tao_ft_naming.exe!main(int argc, char * * argv)  Line 40 + 0x5f
bytes    C++
     tao_ft_naming.exe!__tmainCRTStartup()  Line 555 + 0x19 bytes    C
     tao_ft_naming.exe!mainCRTStartup()  Line 371    C


There is also related problem in the code of the example project
(ace_wrappers\TAO\orbsvcs\tests\ft_naming\Load_Balancing\).

    In the sample server the object group is bound in name service at first
and then it is filled with objects.
Because of this exact sequence client get the "old" initial object group
reference and fails to cast it to required object reference via
Test::Basic::_narrow.
        To make the sample work we need to bind (rebind) group in server
only after the population of the group.

Move (put) the following code right before orb->run() (and not before
adding group members).

      CosNaming::Name name (1);
      name.length (1);
      name[0].id = CORBA::string_dup ("basic_name");
      try {
        (lb_server.name_svc ())->rebind (name, lb_server.object_group ());
      }
      catch (const CORBA::Exception& ex)
      {
        ex._tao_print_exception ("Unable to bind object group in name
service.\n");
        return 1;
      }

Thank you for your attention.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.isis.vanderbilt.edu/pipermail/tao-bugs/attachments/20160425/cf48f871/attachment-0001.html>


More information about the tao-bugs mailing list