[omniORB] Using Any

David Riddoch djr@uk.research.att.com
Thu, 4 Mar 1999 10:03:03 +0000 (GMT)


Hi Steve,


I think this may be a problem I discovered a couple of days ago.

When TypeCodes are marshalled, parts of the on-the-wire representation are
cached so speed-up future marshalling of that TypeCode. In some cases it
turns out that the cached form can depend on the enclosing type (for
example if the TypeCode being marshalled is a member of a structure). If
this TypeCode is then marshalled without the enclosing scope it will be
invalid.

The fix is to disable cached parameter lists in the two versions of
TypeCode_marshaller::marshal() in src/lib/omniORB2/dynamic/typecode.cc
I've put some code below.

Alternatively wait a couple of days, and omniORB 2.7.1 will be out.


Cheers,
David


This is at about line 3222 (and 3504) in
src/lib/omniORB2/dynamic/typecode.cc

      case plt_Complex:
	// Complex parameter list
	{
	  CORBA::Boolean has_cached_paramlist = 0;
	  MemBufferedStream* paramlist = 0;

	  // The typecode is complex and wasn't found, so add it to the
table
	  otbl->addEntry(otbl->currentOffset(), tc);

#if 0
	  // Is there already a cached form of the parameter list?
	  if( !tc->pd_loop_member ) {
	    omni_mutex_lock l(*pd_cached_paramlist_lock);

	    has_cached_paramlist = tc->pd_cached_paramlist != 0;
	  }
#endif

	  if( has_cached_paramlist ) {
	    paramlist = tc->pd_cached_paramlist;
	  } else {
	    // Create a MemBufferedStream to marshal the data into
	    paramlist = new MemBufferedStream();

	    try {
	      // Create a child TypeCode_offsetTable with the correct base
	      // offset.
	      //  NB: When the offsetTable is passed to us, the 
currentOffset
	      // value will indicate the START of the typecode we're
	      // marshalling.  Relative to the start of the encapsulated
	      // data, this location has offset -8, allowing four bytes
for
	      // the TypeCode Kind and four for the encapsulation size.
	      TypeCode_offsetTable offsetTbl(otbl, -8);

	      // Write out the byteorder
	      paramlist->byteOrder() >>= *paramlist;

	      // Call the supplied typecode object to marshal its complex
	      // parameter data into the temporary stream.
	      tc->NP_marshalComplexParams(*paramlist, &offsetTbl);

	      // And we're done!
	    }
	    catch (...) {
	      if( paramlist != 0 )  delete paramlist;
	      throw;
	    }
	  }

	  // Now write the size of the encapsulation out to the main
stream
	  ::operator>>= ((CORBA::ULong)paramlist->alreadyWritten(), s);

	  // And copy the data out to the main stream
	  s.put_char_array((CORBA::Char*) paramlist->data(),
			   paramlist->alreadyWritten());

#if 0
	  // Ensure that the paramlist is freed, or saved as a cached
	  // param list if not a part of a loop.
	  if( !has_cached_paramlist ){
	    if( tc->pd_loop_member ){
	      delete paramlist;
	    }else{
	      omni_mutex_lock l(*pd_cached_paramlist_lock);

	      // Check some other thread hasn't made the parameter list
...
	      if( tc->pd_cached_paramlist == 0 )
		tc->pd_cached_paramlist = paramlist;
	      else
		delete paramlist;
	    }
	  }
#else
          delete paramlist;
#endif
	  break;
	}




On Wed, 3 Mar 1999, Steven W Brenneis wrote:

> I have been experiencing a problem with the CORBA::Any class on omniORB
> 2.7.0 (all patches applied), and was wondering if anyone else has seen
> similar.  This may or may not be related to Judy Anderson's post a
> couple of days ago.
> 
> The problem comes when a CORBA::Any, which has any one of a number of
> variant data structures marshalled into it, is assign to another
> CORBA::Any.  The symptoms from the outside are that the client receiving
> the Any will encounter invalid TypeCode information when marshalling out
> the data structure.  An exception is thrown causing the client to
> terminate the function and, if the data structures are large (> 8192
> bytes of combined data and TypeCode), the server will experience a
> CORBA::COMM_FAILURE (due to the closed pipe).
> 
> It has been verified that the sending application has properly
> marshalled the data into the original Any, but when that Any is assigned
> to another for sending to the client, the typecode information is
> incomplete.
> 
> I have spent hours going through the code and it is very difficult to
> follow because of the heavily recursive nature of the TypeCode parser.
> I have narrowed the problem down to the fact that the underlying AnyP
> class and the TypeCode parser share references to the same
> MemBufferedStream.  If the data structure which is being marshalled into
> the Any also contains complex structures (i.e. sequences, other Any's,
> etc.), the recipient Any uses the cached parameter list from the
> contained TypeCode parser.  Apparently the recipient MemBuffered Stream
> is not being copied from the original cached parameter list, but instead
> is simply being re-allocated on the heap.  This does not happen
> consistently and the nesting level of the contained structures must be
> deep.
> 
> Clear as mud, right?  As I said, this is heavily recursive code so the
> above explanation may not be correct, but hopefully close enough in case
> someone else has seen similar. 
> 
> Steve Brenneis