[omniORB] Problem with deeply nested structs.

baileyk@schneider.com baileyk@schneider.com
Thu, 14 Mar 2002 16:28:53 -0600


I'm considering using omniORB4 in a production environment in conjunction
with Orbix2000.  I started doing a few stress tests to find breaking points
and figured I'd report one of them.  Maybe someone will test with the
latest
snapshot and let me know if it is still broken.  The case is a bit
pathological anyway.  I found that omniORB4 SEGVs if it tries to return
a deeply nested recursive structure.  In the python script below, I can
push
the test_size value to over 50000 before I get problems, but only if the
implementation of bar2() just echos back the input parameter.  If I
transform
the input parameter into a linked list structure (if I -DNESTED during
compile),
the input length can not exceed 2050.  Perhaps I'm mishandling memory in
some
obscure way.  omniORB3 behaves the same way and orbix2000 v1.2.1 is not
much
better, it dies with a list of size 2700

If anyone has 5 minutes to try it, I'd appreciate knowing if it has been
fixed
in the latest snapshot. Or tell me what's wrong with such deeply nested
structs!

Thanks!

Kendall Bailey

p.s. I'm using Solaris 8, with
Sun WorkShop 6 update 2 C++ 5.3 Patch 111685-05 2002/02/03

Here's the IDL:

#ifndef O2K_OMNI_TEST_IDL_
#define O2K_OMNI_TEST_IDL_

module o2k_omni_test {
   struct param {
      string val;
      sequence<param> more;
   };
   interface foo {
      long bar();
      param bar2( in param v );
   };
};

#endif

Here's the server program:

//--------------------------------------------
#include "o2k_omni_test.hh"

class foo_imp :
   public virtual PortableServer::RefCountServantBase,
   public virtual POA_o2k_omni_test::foo
{
public:
   CORBA::Long bar();

   o2k_omni_test::param* bar2( o2k_omni_test::param const& v );
};
//--------------------------------------------
CORBA::Long
foo_imp::bar()
{
   return 0;
}
//--------------------------------------------
o2k_omni_test::param*
foo_imp::
bar2( o2k_omni_test::param const& v )
{
   o2k_omni_test::param* rv = new o2k_omni_test::param;
#ifdef NESTED
   rv->val = v.val;
   o2k_omni_test::param* next = rv;
   for( int i = 0; i < v.more.length() ; ++i )
   {
      next->more.length(1);
      next->more[0].val = v.more[i].val;
      next = &(next->more[0]);
   }
#else
   *rv = v;
#endif
   return rv;
}
//--------------------------------------------
int main(int argc, char *argv[])
{
   CORBA::ORB_var gOrb = CORBA::ORB_init(argc, argv);
   CORBA::Object_var obj = gOrb->resolve_initial_references("RootPOA");
   PortableServer::POA_var poa = PortableServer::POA::_narrow(obj.in());
   PortableServer::POAManager_var mgr = poa->the_POAManager();
   mgr->activate();
   obj = gOrb->resolve_initial_references("NameService");
   CosNaming::NamingContext_var ns =
      CosNaming::NamingContext::_narrow( obj.in() );
   CosNaming::Name n;
   n.length(1);
   n[0].id = CORBA::string_dup("o2k_omni_test");
   n[0].kind = CORBA::string_dup("obj");
   PortableServer::ServantBase_var s(new foo_imp);
   obj = poa->servant_to_reference( s.in() );
   ns->rebind( n, obj.in() );
   gOrb->run();

   return 0;
}

//------------------------------------------------------


And here's an python script to call the server

#!/bin/env python

from CosNaming import NameComponent, NamingContext
from CORBA import ORB_init
from o2k_omni_test import *
import sys

test_size = 2100

orb = ORB_init(sys.argv)
obj = orb.resolve_initial_references("NameService")
ns = obj._narrow( NamingContext )

n = [ NameComponent("o2k_omni_test","obj") ]

obj = ns.resolve( n )
s = obj._narrow( foo )

p = param( "a test string", [] )

for i in range(test_size) :
   p.more.append( param( p.val, [] ) )

r = s.bar2( p )

print "done."