Fix: omniidl2 generates bad code for user exceptions

Juergen Keil jk@leo.tools.de
Wed, 6 Aug 1997 18:30:21 +0200


After adding the #pragma prefix "omg.org" line to Naming.idl, so that
omniORB can talk to the JavaIDL nameserver, I had some problems with
the echo/eg3_impl example.  It ran fine when eg3_impl was started for
the first time, but after killing eg3_impl and running if for a second
time it always crashed with a system exception.

When running eg3_impl for the second time, the object is still bound on
the nameserver from a previous invocation and the bind method
invocation should get a CosNaming::NamingContext::AlreadyBound
exception, so that eg3_impl tries to rebind the object instead.  But
instead of the AlreadyBound exception, a CORBA::MARSHAL exception occurs!


The problem is caused by omniidl2, which generates bad code for the
proxy stubs when user exceptions have to be handled: The length of the
longest repository id for all exceptions that can occur (the 49 in the
code below) is mis-calculated.  Here's the relevant code from
NamingSK.cc, generated for Naming.idl with the added
#pragma prefix "omg.org" line:


      case GIOP::USER_EXCEPTION:
      {  
        CORBA::Char _excId[49];
        CORBA::ULong _len;
        _len <<= _c;
        if (_len > 49) {
          _c.RequestCompleted(1);
          throw CORBA::MARSHAL(0,CORBA::COMPLETED_MAYBE);
        }
        else {
          _c.get_char_array(_excId,_len);
        }

Since ``IDL:omg.org/CosNaming/NamingContext/AlreadyBound:1.0'' has a length
of 53 bytes (including the terminating \0) the AlreadyBound exception
cannot be processed by the proxy stubs because the local _excId buffer
is to small and a CORBA::MARSHAL exception is thrown instead.

The bogus number 49 is calculated by omniidl2 as the maximum of all
excpt->repoIdConstLen() for all exceptions that can occur, but
excpt->repoIdConstLen() returns the length of the pre-processor macro (!)
that contains the repository id for the exception (aka 
CosNaming_NamingContext_AlreadyBound_IntfRepoID).


The following patch to omniidl2 fixes the problem:

diff -rc3 omniORB_2.2.0-orig/src/tool/omniidl2/omniORB2_be/o2be_exception.cc omniORB_2.2.0/src/tool/omniidl2/omniORB2_be/o2be_exception.cc
*** omniORB_2.2.0-orig/src/tool/omniidl2/omniORB2_be/o2be_exception.cc  Tue May  6 15:54:52 1997
--- omniORB_2.2.0/src/tool/omniidl2/omniORB2_be/o2be_exception.cc       Wed Aug  6 17:18:06 1997
***************
*** 45,51 ****
    pd_repoid = new char[strlen(_fqname())+strlen(IRREPOID_POSTFIX)+1];
    strcpy(pd_repoid,_fqname());
    strcat(pd_repoid,IRREPOID_POSTFIX);
!   pd_repoidsize = strlen(pd_repoid)+1;
  }
  
  void
--- 45,51 ----
    pd_repoid = new char[strlen(_fqname())+strlen(IRREPOID_POSTFIX)+1];
    strcpy(pd_repoid,_fqname());
    strcat(pd_repoid,IRREPOID_POSTFIX);
!   pd_repoidsize = strlen(repositoryID()) + 1;
  }
  
  void

--
Juergen Keil          jk@tools.de ...!{uunet,mcsun}!unido!tools!jk