[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference pamsrc::objectbroker_development

Title:ObjectBroker Development - BEA Systems' CORBA
Notice:See note 2 for kit locations; note 4 for training
Moderator:RECV::GUMBELd
Created:Thu Dec 27 1990
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2482
Total number of notes:13057

2445.0. "sequence of structure with bounded strings - problem" by LEMAN::DONALDSON (Froggisattva! Froggisattva!) Mon Mar 03 1997 06:10

v2.7-11, NT4/Win95, C++ bindings.

A project I work with is having problems with bounded strings.
I summarize the problem like this: we have problems when we
exceed a certain limit when we try to use unbouded sequences
of structures containing bounded strings.

Here's a summary of the tests I've made so far:

Test 1: unbounded sequence of unbounded strings works well up to 1600 strings 
of 100. (Didn't try further).

Test 2: unbounded sequence of bounded strings works well up to 1600 strings of
10. (However, I can also create and return a sequence of strings of 100 with no
problem!).

Test 3: unbounded sequence of struct of 3 bounded strings of 10 and 1 unbounded
string. Client detects exception:
	    OBB_INV_MRSHEXCBUF (e), Exceeded marshalling buffer.
with 272 elements in the sequence.
Less than that it seems to work. More than 272 provokes a crash on the server.

Test 4: unbounded sequence of a struct containing 4 unbounded strings. No
problems detected.

Test 5: unbounded sequence of struct of 4 bounded strings of 10.
Client detects exception:
	    OBB_INV_MRSHEXCBUF (e), Exceeded marshalling buffer.
with 271 elements in the sequence.
Less than that it seems to work. More than 271 provokes a crash on the server.

Test 6: unbounded sequence of a struct with just one bounded string of 10. This 
starts having problems at 1082 items. ("Exceeded marshaling buffer..."). Some
weird stuff if I set strings less than 10 (the string bound). I can for example 
create a sequence of 1000 strings of 6, but not of 5!

In subsequent replies I'll give you the idl, a sample method and the calling
client.

John D.
T.RTitleUserPersonal
Name
DateLines
2445.1the idlLEMAN::DONALDSONFroggisattva! Froggisattva!Mon Mar 03 1997 06:11106
module m1
{
    typedef sequence<string> tUseqUstr;
    typedef string<10> tBstr10;
    typedef sequence<tBstr10> tUseqBstr10;
    typedef struct tUDT1_ 
    {
        tBstr10		Bstr10_1;
        tBstr10		Bstr10_2;
        tBstr10		Bstr10_3;
        string		Ustr;
    } tUDT1;
    typedef sequence<tUDT1> tUseqUDT1;
    typedef struct tUDT2_ 
    {
        string		Ustr_1;
        string		Ustr_2;
        string		Ustr_3;
        string		Ustr_4;
    } tUDT2;
    typedef sequence<tUDT2> tUseqUDT2;
    typedef struct tUDT3_ 
    {
        tBstr10		Bstr10_1;
        tBstr10		Bstr10_2;
        tBstr10		Bstr10_3;
        tBstr10		Bstr10_4;
    } tUDT3;
    typedef sequence<tUDT3> tUseqUDT3;
    typedef struct tUDT4_ 
    {
        tBstr10		Bstr10_1;
    } tUDT4;
    typedef sequence<tUDT4> tUseqUDT4;

    interface i1
    {
        void OUseqUstr
        (
		in long totalUseq,
			in long totalUstr,
            out tUseqUstr oseq
        );

        void OUseqBstr10
        (
		in long totalUseq,
			in long totalBstr,
            out tUseqBstr10 oseq
        );

        void OUseqUDT1
        (
		in long totalUseq,
			in long totalUstr,
				in long totalBstr,
            out tUseqUDT1 oseq
        );

        void OUseqUDT2
        (
		in long totalUseq,
			in long totalUstr,
            out tUseqUDT2 oseq
        );

        void OUseqUDT3
        (
		in long totalUseq,
			in long totalBstr,
            out tUseqUDT3 oseq
        );

        void OUseqUDT4
        (
		in long totalUseq,
			in long totalBstr,
            out tUseqUDT4 oseq
        );

    };

};
#pragma repository_id( "m1::tUseqUstr", "7b1ed45fb488.02.c1.50.32.68.00.00.00")
#pragma interface_id( "m1::i1", "7b1ed45fb489.02.c1.50.32.68.00.00.00")
#pragma operation_id( "m1::i1::OUseqUstr", "7b1ed45fb48a.02.c1.50.32.68.00.00.00", 1)
#pragma repository_id( "m1::tBstr10", "7b1fb93f4bb2.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUseqBstr10", "7b1fb93f4bb3.02.c1.50.32.68.00.00.00")
#pragma operation_id( "m1::i1::OUseqBstr10", "7b1fb93f4bb4.02.c1.50.32.68.00.00.00", 2)
#pragma repository_id( "m1::tUDT1_", "7b21560765c1.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUDT1", "7b21560765c2.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUseqUDT1", "7b21560765c3.02.c1.50.32.68.00.00.00")
#pragma operation_id( "m1::i1::OUseqUDT1", "7b21560765c4.02.c1.50.32.68.00.00.00", 3)
#pragma repository_id( "m1::tUDT2_", "7b21a6e42c8b.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUDT2", "7b21a6e42c8c.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUseqUDT2", "7b21a6e42c8d.02.c1.50.32.68.00.00.00")
#pragma operation_id( "m1::i1::OUseqUDT2", "7b21a6e42c8e.02.c1.50.32.68.00.00.00", 4)
#pragma repository_id( "m1::tUDT3_", "7b21c3cdd19f.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUDT3", "7b21c3cdd1a0.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUseqUDT3", "7b21c3cdd1a1.02.c1.50.32.68.00.00.00")
#pragma operation_id( "m1::i1::OUseqUDT3", "7b21c3cdd1a2.02.c1.50.32.68.00.00.00", 5)
#pragma repository_id( "m1::tUDT4_", "7b2819b9ad65.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUDT4", "7b2819b9ad66.02.c1.50.32.68.00.00.00")
#pragma repository_id( "m1::tUseqUDT4", "7b2819b9ad67.02.c1.50.32.68.00.00.00")
#pragma operation_id( "m1::i1::OUseqUDT4", "7b2819b9ad68.02.c1.50.32.68.00.00.00", 6)

2445.2a sample methodLEMAN::DONALDSONFroggisattva! Froggisattva!Mon Mar 03 1997 06:2092
/*
 *
 *  ROUTINE NAME:	i1Impl::i1Impl_OUseqUDT1
 *
 *  FUNCTIONAL DESCRIPTION:
 *
 *      Method routine for OUseqUDT1.
 *       (Implementation : i1Impl)
 *
 */


 void i1Impl::i1Impl_OUseqUDT1 (
    CORBA::Long totalUseq,
    CORBA::Long totalUstr,
    CORBA::Long totalBstr,
    m1::tUseqUDT1 *& oseq,
    CORBA::Environment & ev)

{

/* OBB_PRESERVE_BEGIN(i1Impl::i1Impl_OUseqUDT1) */
	 cout << endl << "Entering i1Impl::i1Impl_OUseqUDT1" << endl;
	 cout << "    totalUseq=" << totalUseq << endl;
	 cout << "    totalUstr=" << totalUstr << endl;
	 cout << "    totalBstr=" << totalBstr << endl;

	// create the buffer of the sequence
	 m1::tUDT1 *seqBuffer = m1::tUseqUDT1::allocbuf( totalUseq);

	// make strings and build them into the sequence buffer
	for (short i=0; i<totalUseq; i++)
	{
		m1::tUDT1 *pUDT = &((seqBuffer)[i]);

		m1::tBstr10 Bstr = (m1::tBstr10)malloc(totalBstr+1);
		for (short j=0; j<totalBstr; j++)
		{
			Bstr[j] = 'a';
		}
		Bstr[totalBstr] = '\0';
		pUDT->Bstr10_1 = Bstr;

		Bstr = (m1::tBstr10)malloc(totalBstr+1);
		for (j=0; j<totalBstr; j++)
		{
			Bstr[j] = 'b';
		}
		Bstr[totalBstr] = '\0';
		pUDT->Bstr10_2 = Bstr;

		Bstr = (m1::tBstr10)malloc(totalBstr+1);
		for (j=0; j<totalBstr; j++)
		{
		Bstr[j] = 'c';
		}
		Bstr[totalBstr] = '\0';
		pUDT->Bstr10_3 = Bstr;

		CORBA::Char *Ustr = (CORBA::Char*)malloc(totalUstr+1);
		for (j=0; j<totalUstr; j++)
		{
		Ustr[j] = 'd';
		}
		Ustr[totalUstr] = '\0';
		pUDT->Ustr = Ustr;

	}

	// construct the sequence
	oseq = new m1::tUseqUDT1( totalUseq, totalUseq, seqBuffer, CORBA_TRUE);

	// print out the result locally to check its ok
	cout << endl;
	cout << "maximum=" << oseq->maximum() << endl;
	cout << "length =" << oseq->length() << endl;
	for (i=0; i<long(oseq->length()); i++)
	{
		m1::tUDT1 *pUDT = &((*oseq)[i]);
		cout << 
			"<" << pUDT->Bstr10_1 << "> " << 
			"<" << pUDT->Bstr10_2 << "> " << 
			"<" << pUDT->Bstr10_3 << "> " << 
			"<" << pUDT->Ustr << "> " << i << endl;
	};
	cout << endl;
	cout << "Exiting i1Impl::i1Impl_OUseqUDT1" << endl;
	
/* OBB_PRESERVE_END(i1Impl::i1Impl_OUseqUDT1) */
    return ;
}

2445.3the calling clientLEMAN::DONALDSONFroggisattva! Froggisattva!Mon Mar 03 1997 06:2438
void TestUseqUDT1( m1::i1_ptr i1Ptr)
{
	CORBA::Environment ev;
	m1::tUseqUDT1 *theSeq;
	short seqSize;
	short uStrSize;
	short bStrSize;

	cout << endl << "Test: Unbounded sequence of user-defined type 1" << endl;
	cout << "Size of unbounded sequence: " << flush;
	cin >> seqSize;
	cout << "Size of unbounded string: " << flush;
	cin >> uStrSize;
	cout << "Size of bounded string: " << flush;
	cin >> bStrSize;

	i1Ptr->OUseqUDT1( seqSize, uStrSize, bStrSize, theSeq, ev);
	exitIfException( &ev, "i1Ptr->OUseqUDT1");

	cout << endl;
	cout << "maximum=" << theSeq->maximum() << endl;
	cout << "length =" << theSeq->length() << endl;
	for (short i=0; i<long(theSeq->length()); i++)
	{
		m1::tUDT1 *pUDT = &((*theSeq)[i]);
		cout << 
			"<" << pUDT->Bstr10_1 << "> " << 
			"<" << pUDT->Bstr10_2 << "> " << 
			"<" << pUDT->Bstr10_3 << "> " << 
			"<" << pUDT->Ustr << "> " << i << endl;
	};
	cout << endl;

	// clean up. Do we need to freebuf first?
	delete theSeq;
};


2445.4some questions and observationsLEMAN::DONALDSONFroggisattva! Froggisattva!Mon Mar 03 1997 06:4226
- is the general approach ('allocbuf' + 'new') for creating sequences
  recommended? Or should I prefer 'new' plus '[]'?

- is the use of malloc in the method okay? (For example, should I
  create a string_ptr instead?).

- do I need the trailing zero at the end of the strings?

- should the client just 'delete' or should it freebuf (or 
  anything else?)?

- the other tests use exactly the same techniques to successfully
  send sequences of:
	unbounded strings
	bounded strings
	structures of unbounded strings

- sequences of structures containing 1 bounded string can be up to 1080 long.
  sequences of structures containing 4 bounded strings can be up to 270 long.
  After this limit they fail with 'exceeded message buffer' (see note .0).
  Is the factor of 4 here significant?
  If you push up the count a bit further the server just crashes after the 
  method exits (the sequence appears to be well-constrcuted in the sense
  that I can print it out).
  
John D.
2445.5REQUE::BOWERPeter Bower, ObjectBrokerFri Mar 07 1997 11:4949
    
    
>  is the general approach ('allocbuf' + 'new') for creating sequences
>  recommended? Or should I prefer 'new' plus '[]'?
    
    allocbuf and then new will work. You could also do new and then a
    call to set the length. CORBA does not allow you to do a [] without
    first setting the length.
    

> is the use of malloc in the method okay? (For example, should I
>  create a string_ptr instead?).

    No! The C++ bindings release the memory that you return. Therefore,
    the allocation and deallocation mechanisms must match. CORBA states
    that strings should be allocated using CORBA::string_alloc and
    released via CORBA::string_free. Therefore, change your use
    of malloc to string_alloc and remove the + 1 - string_alloc allocates
    the byte for the null for you. When I ran you program through
    purify on nt, I saw lots of free errors due to the fact that you
    use malloc and we do not use free.
    
> do I need the trailing zero at the end of the strings?

     Yes. CORBA states that all strings are null terminated.
    
> should the client just 'delete' or should it freebuf (or 
  anything else?)?

    The client 'deletes'. The out sequence is a class; it contains a buffer
    but deleting the class releases all buffers and data within the
    buffers.
    
> the other tests use exactly the same techniques to successfully
> send sequences of:
>  Is the factor of 4 here significant?
    
    Most likely the factor of 4 is not significant. OBB calculates the
    length of the buffer to marshall into by walking the returned
    data. It then allocates the buffer and then walks the returned
    data and marshalls it. There appears to be an error in the
    calculation of the length and OBB is writing over the end of
    the buffer. There is extra space at the end of the buffer so
    it takes a large sequence to demonstrate the problem.
    
    I have reproduced it here.
    
    
    
2445.6REQUE::BOWERPeter Bower, ObjectBrokerFri Mar 07 1997 13:014
    
    This is a similar problem to qar 3468. I will investigate
    putting the fix into arches and will send you a workaround.
    
2445.7LEMAN::DONALDSONFroggisattva! Froggisattva!Mon Mar 10 1997 10:196
Peter,

thanks for the clarification. I'll fix my test code
to do as you propose.

John D.