[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