diff options
-rw-r--r-- | TAO/ChangeLog | 24 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_sequence/any_op_cs.cpp | 7 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_structure/any_op_cs.cpp | 7 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_union/any_op_cs.cpp | 7 | ||||
-rw-r--r-- | TAO/tao/AnyTypeCode/Any.cpp | 15 | ||||
-rw-r--r-- | TAO/tests/Bug_2234_Regression/Bug_2234_Regression.mpc | 24 | ||||
-rw-r--r-- | TAO/tests/Bug_2234_Regression/Test.idl | 41 | ||||
-rw-r--r-- | TAO/tests/Bug_2234_Regression/client.cpp | 332 | ||||
-rwxr-xr-x | TAO/tests/Bug_2234_Regression/run_test.pl | 48 | ||||
-rw-r--r-- | TAO/tests/Bug_2234_Regression/server.cpp | 748 |
10 files changed, 1244 insertions, 9 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 76149a98c7b..4ecf50318c7 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,27 @@ +Tue Sep 13 10:30:00 UTC 2005 Simon Massey <sma@prismtech.com> + + * tao/AnyTypeCode/Any.cpp + + * TAO_IDL/be/be_visitor_sequence/any_op_cs.cpp + * TAO_IDL/be/be_visitor_structure/any_op_cs.cpp + * TAO_IDL/be/be_visitor_union/any_op_cs.cpp + + * tests/Bug_2234_Regression/Bug_2234_Regression.mpc + * tests/Bug_2234_Regression/Test.idl + * tests/Bug_2234_Regression/client.cpp + * tests/Bug_2234_Regression/run_test.pl + * tests/Bug_2234_Regression/server.cpp + + This fixes bug 2234. + The Portiable Interception call to arguments() attempts to create + a read-only copy of all arguments passed into the current method. + Unfortunatly during the call to receive_request() the "out" args + of variable length types have not yet been allocated by the server + and so are NULL pointers. A deep copy was being attempted which + de-referenced these NULLs causing a crash. Explicit NULL checks + are now performed for these types and a NULL pointer to the type + is placed into the arg list instead. + Tue Sep 13 10:18:12 UTC 2005 Martin Corino <mcorino@remedy.nl> * tests/Portable_Interceptors/Bug_1559/run_test.pl: diff --git a/TAO/TAO_IDL/be/be_visitor_sequence/any_op_cs.cpp b/TAO/TAO_IDL/be/be_visitor_sequence/any_op_cs.cpp index 577ca1ecc3d..a614ac55509 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence/any_op_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence/any_op_cs.cpp @@ -89,13 +89,18 @@ be_visitor_sequence_any_op_cs::visit_sequence (be_sequence *node) << "const " << node->name () << " &_tao_elem" << be_uidt_nl << ")" << be_uidt_nl << "{" << be_idt_nl + + << "if (0 == &_tao_elem) // Trying to de-reference NULL object" << be_idt_nl + << "_tao_any <<= static_cast<" << node->name () << " *>( 0 ); // Use non-copying insertion of a NULL" << be_uidt_nl + << "else" << be_idt_nl + << "TAO::Any_Dual_Impl_T<" << node->name () << ">::insert_copy (" << be_idt << be_idt_nl << "_tao_any," << be_nl << node->name () << "::_tao_any_destructor," << be_nl << node->tc_name () << "," << be_nl << "_tao_elem" << be_uidt_nl - << ");" << be_uidt << be_uidt_nl + << ");" << be_uidt << be_uidt << be_uidt_nl << "}" << be_nl << be_nl; // Non-copying insertion. diff --git a/TAO/TAO_IDL/be/be_visitor_structure/any_op_cs.cpp b/TAO/TAO_IDL/be/be_visitor_structure/any_op_cs.cpp index cf4356a4806..bbb3250ab5f 100644 --- a/TAO/TAO_IDL/be/be_visitor_structure/any_op_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_structure/any_op_cs.cpp @@ -90,13 +90,18 @@ be_visitor_structure_any_op_cs::visit_structure (be_structure *node) << "const " << node->name () << " &_tao_elem" << be_uidt_nl << ")" << be_uidt_nl << "{" << be_idt_nl + + << "if (0 == &_tao_elem) // Trying to de-reference NULL object" << be_idt_nl + << "_tao_any <<= static_cast<" << node->name () << " *>( 0 ); // Use non-copying insertion of a NULL" << be_uidt_nl + << "else" << be_idt_nl + << "TAO::Any_Dual_Impl_T<" << node->name () << ">::insert_copy (" << be_idt << be_idt_nl << "_tao_any," << be_nl << node->name () << "::_tao_any_destructor," << be_nl << node->tc_name () << "," << be_nl << "_tao_elem" << be_uidt_nl - << ");" << be_uidt << be_uidt_nl + << ");" << be_uidt << be_uidt << be_uidt_nl << "}" << be_nl << be_nl; // Non-copying insertion. diff --git a/TAO/TAO_IDL/be/be_visitor_union/any_op_cs.cpp b/TAO/TAO_IDL/be/be_visitor_union/any_op_cs.cpp index 3e16d48b1c7..62532ab116b 100644 --- a/TAO/TAO_IDL/be/be_visitor_union/any_op_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_union/any_op_cs.cpp @@ -90,13 +90,18 @@ be_visitor_union_any_op_cs::visit_union (be_union *node) << "const " << node->name () << " &_tao_elem" << be_uidt_nl << ")" << be_uidt_nl << "{" << be_idt_nl + + << "if (0 == &_tao_elem) // Trying to de-reference NULL object" << be_idt_nl + << "_tao_any <<= static_cast<" << node->name () << " *>( 0 ); // Use non-copying insertion of a NULL" << be_uidt_nl + << "else" << be_idt_nl + << "TAO::Any_Dual_Impl_T<" << node->name () << ">::insert_copy (" << be_idt << be_idt_nl << "_tao_any," << be_nl << node->name () << "::_tao_any_destructor," << be_nl << node->tc_name () << "," << be_nl << "_tao_elem" << be_uidt_nl - << ");" << be_uidt << be_uidt_nl + << ");" << be_uidt << be_uidt << be_uidt_nl << "}" << be_nl << be_nl; // Non-copying insertion. diff --git a/TAO/tao/AnyTypeCode/Any.cpp b/TAO/tao/AnyTypeCode/Any.cpp index ed5f9a7715e..2509cfbe947 100644 --- a/TAO/tao/AnyTypeCode/Any.cpp +++ b/TAO/tao/AnyTypeCode/Any.cpp @@ -449,12 +449,15 @@ operator<<= (CORBA::Any &any, CORBA::LongDouble ld) void operator<<= (CORBA::Any &any, const CORBA::Any &a) { - TAO::Any_Dual_Impl_T<CORBA::Any>::insert_copy ( - any, - CORBA::Any::_tao_any_destructor, - CORBA::_tc_any, - a - ); + if (0 == &a) // Trying to de-reference NULL Any + any <<= static_cast<CORBA::Any *>( 0 ); // Use non-copying insertion of a NULL + else + TAO::Any_Dual_Impl_T<CORBA::Any>::insert_copy ( + any, + CORBA::Any::_tao_any_destructor, + CORBA::_tc_any, + a + ); } // Insertion of Any - non-copying. diff --git a/TAO/tests/Bug_2234_Regression/Bug_2234_Regression.mpc b/TAO/tests/Bug_2234_Regression/Bug_2234_Regression.mpc new file mode 100644 index 00000000000..6ae49e52085 --- /dev/null +++ b/TAO/tests/Bug_2234_Regression/Bug_2234_Regression.mpc @@ -0,0 +1,24 @@ +// -*- MPC -*- +// $Id$ + + +project (*client) : taoclient,anytypecode { + IDL_Files { + Test.idl + } + + Source_Files { + TestC.cpp + client.cpp + } +} + +project (*server) : taoserver,pi_server { + IDL_Files { + Test.idl + } + + Source_Files { + server.cpp + } +} diff --git a/TAO/tests/Bug_2234_Regression/Test.idl b/TAO/tests/Bug_2234_Regression/Test.idl new file mode 100644 index 00000000000..5843ece7d9e --- /dev/null +++ b/TAO/tests/Bug_2234_Regression/Test.idl @@ -0,0 +1,41 @@ +// $Id$ + +module Test +{ + struct MyNonVarStruct { + long val; + }; + + struct MyVarStruct { + string val; + }; + + union MyNonVarUnion switch(short) { + case 1: + long valLong; + case 2: + short valShort; + }; + + union MyVarUnion switch(short) { + case 1: + long valLong; + case 2: + string valString; + }; + + typedef sequence< long > MySeqOfLong; + + interface Foo + { + long TestLong( in long a, out long b, inout long c ); + string TestString( in string a, out string b, inout string c ); + MyNonVarStruct TestNonVarStruct( in MyNonVarStruct a, out MyNonVarStruct b, inout MyNonVarStruct c ); + MyVarStruct TestVarStruct( in MyVarStruct a, out MyVarStruct b, inout MyVarStruct c ); + MyNonVarUnion TestNonVarUnion( in MyNonVarUnion a, out MyNonVarUnion b, inout MyNonVarUnion c ); + MyVarUnion TestVarUnion( in MyVarUnion a, out MyVarUnion b, inout MyVarUnion c ); + MySeqOfLong TestSeqOfLong( in MySeqOfLong a, out MySeqOfLong b, inout MySeqOfLong c ); + any TestAny( in any a, out any b, inout any c ); + oneway void ShutdownServer(); + }; +}; diff --git a/TAO/tests/Bug_2234_Regression/client.cpp b/TAO/tests/Bug_2234_Regression/client.cpp new file mode 100644 index 00000000000..98a8dac2833 --- /dev/null +++ b/TAO/tests/Bug_2234_Regression/client.cpp @@ -0,0 +1,332 @@ +// $Id$ + +// Regression test Bug 2234 +// +// The bug manifests itself in the server. + +#include "TestC.h" +#include "ace/OS_NS_string.h" + +int +main( + int argc, + char** argv) +{ + ACE_DECLARE_NEW_CORBA_ENV; + + ::CORBA::Boolean testFailed= 0; + ACE_DEBUG( (LM_INFO, "Regression test for Bug 2234 (Interceptor arg list with var len out params)\n")); + ACE_TRY + { + CORBA::ORB_var + orb= CORBA::ORB_init( argc, argv, 0 ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + CORBA::Object_var + object= orb->string_to_object( "file://server.ior" ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + Test::Foo_var + foo= Test::Foo::_narrow( object.in() ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + + //----------------------------------------------------------------------- + ::CORBA::Long + aL= 1, + bL, + cL= 3, + rL= 0; + ACE_DEBUG( (LM_INFO, ". Long() ") ); + rL= foo->TestLong( aL, bL, cL ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG( (LM_INFO, "a is %d, b is %d, c is %d, r is %d: ", aL, bL, cL, rL) ); + if (static_cast<CORBA::Long>(1) != aL) { + ACE_DEBUG( (LM_ERROR, "a is wrong\n") ); testFailed= 1;} + else if (static_cast<CORBA::Long>(2) != bL) { + ACE_DEBUG( (LM_ERROR, "b is wrong\n") ); testFailed= 1;} + else if (static_cast<CORBA::Long>(4) != cL) { + ACE_DEBUG( (LM_ERROR, "c is wrong\n") ); testFailed= 1;} + else if (static_cast<CORBA::Long>(7) != rL) { + ACE_DEBUG( (LM_ERROR, "r is wrong\n") ); testFailed= 1;} + else + ACE_DEBUG( (LM_INFO, "OK\n") ); + + //----------------------------------------------------------------------- + ::CORBA::String_var + aS= CORBA::string_dup("1"), + bS, + cS= CORBA::string_dup("3"), + rS; + ACE_DEBUG( (LM_INFO, ". String() ") ); + rS= foo->TestString( aS, bS, cS ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG( (LM_INFO, "a is %s, b is %s, c is %s, r is %s: ", aS.in(), bS.in(), cS.in(), rS.in()) ); + if ((0 != *aS.in()) && (0 != ACE_OS::strcmp(aS.in(), "1"))) { + ACE_DEBUG( (LM_ERROR, "a is wrong\n") ); testFailed= 1;} + else if ((0 != *aS.in()) && (0 != ACE_OS::strcmp(bS.in(), "2"))) { + ACE_DEBUG( (LM_ERROR, "b is wrong\n") ); testFailed= 1;} + else if ((0 != *aS.in()) && (0 != ACE_OS::strcmp(cS.in(), "4"))) { + ACE_DEBUG( (LM_ERROR, "c is wrong\n") ); testFailed= 1;} + else if ((0 != *aS.in()) && (0 != ACE_OS::strcmp(rS.in(), "7"))) { + ACE_DEBUG( (LM_ERROR, "r is wrong\n") ); testFailed= 1;} + else + ACE_DEBUG( (LM_INFO, "OK\n") ); + + //----------------------------------------------------------------------- + ::Test::MyNonVarStruct_var + aFS= new ::Test::MyNonVarStruct(), + bFS= new ::Test::MyNonVarStruct(), + cFS= new ::Test::MyNonVarStruct(), + rFS; + aFS->val= 1; + cFS->val= 3; + ACE_DEBUG( (LM_INFO, ". MyNonVarStruct() ") ); + rFS= foo->TestNonVarStruct( aFS, bFS, cFS ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG( (LM_INFO, "a is %d, b is %d, c is %d, r is %d: ", aFS.in().val, bFS.in().val, cFS.in().val, rFS.in().val) ); + if (static_cast<CORBA::Long>(1) != aFS->val) { + ACE_DEBUG( (LM_ERROR, "a is wrong\n") ); testFailed= 1;} + else if (static_cast<CORBA::Long>(2) != bFS->val) { + ACE_DEBUG( (LM_ERROR, "b is wrong\n") ); testFailed= 1;} + else if (static_cast<CORBA::Long>(4) != cFS->val) { + ACE_DEBUG( (LM_ERROR, "c is wrong\n") ); testFailed= 1;} + else if (static_cast<CORBA::Long>(7) != rFS->val) { + ACE_DEBUG( (LM_ERROR, "r is wrong\n") ); testFailed= 1;} + else + ACE_DEBUG( (LM_INFO, "OK\n") ); + + //----------------------------------------------------------------------- + ::Test::MyVarStruct_var + aVS= new ::Test::MyVarStruct(), + bVS, + cVS= new ::Test::MyVarStruct(), + rVS; + aVS->val= CORBA::string_dup("1"); + cVS->val= CORBA::string_dup("3"); + ACE_DEBUG( (LM_INFO, ". MyVarStruct() ") ); + rVS= foo->TestVarStruct( aVS, bVS, cVS ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG( (LM_INFO, "a is %s, b is %s, c is %s, r is %s: ", aVS->val.in(), bVS->val.in(), cVS->val.in(), rVS->val.in()) ); + if ((0 != *aVS->val) && (0 != ACE_OS::strcmp(aVS->val, "1"))) { + ACE_DEBUG( (LM_ERROR, "a is wrong\n") ); testFailed= 1;} + else if ((0 != *bVS->val) && (0 != ACE_OS::strcmp(bVS->val, "2"))) { + ACE_DEBUG( (LM_ERROR, "b is wrong\n") ); testFailed= 1;} + else if ((0 != *cVS->val) && (0 != ACE_OS::strcmp(cVS->val, "4"))) { + ACE_DEBUG( (LM_ERROR, "c is wrong\n") ); testFailed= 1;} + else if ((0 != *rVS->val) && (0 != ACE_OS::strcmp(rVS->val, "7"))) { + ACE_DEBUG( (LM_ERROR, "r is wrong\n") ); testFailed= 1;} + else + ACE_DEBUG( (LM_INFO, "OK\n") ); + + //----------------------------------------------------------------------- + ::Test::MyNonVarUnion_var + aFU= new ::Test::MyNonVarUnion(), + bFU= new ::Test::MyNonVarUnion(), + cFU= new ::Test::MyNonVarUnion(), + rFU; + aFU->valLong( static_cast<CORBA::Long>(1) ); + cFU->valLong( static_cast<CORBA::Long>(3) ); + ACE_DEBUG( (LM_INFO, ". MyNonVarUnion() ") ); + rFU= foo->TestNonVarUnion( aFU, bFU, cFU ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG( (LM_INFO, "a is ") ); + if (static_cast<CORBA::Short>(1) != aFU->_d()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", aFU->valLong()) ); + ACE_DEBUG( (LM_INFO, ", b is ") ); + if (static_cast<CORBA::Short>(1) != bFU->_d()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", bFU->valLong()) ); + ACE_DEBUG( (LM_INFO, ", c is ") ); + if (static_cast<CORBA::Short>(1) != cFU->_d()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", cFU->valLong()) ); + ACE_DEBUG( (LM_INFO, ", r is ") ); + if (static_cast<CORBA::Short>(1) != rFU->_d()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", rFU->valLong()) ); + ACE_DEBUG( (LM_INFO, ": ") ); + if ((static_cast<CORBA::Short>(1) != aFU->_d()) || (static_cast<CORBA::Long>(1) != aFU->valLong())) { + ACE_DEBUG( (LM_ERROR, "a is wrong\n") ); testFailed= 1;} + else if ((static_cast<CORBA::Short>(1) != bFU->_d()) || (static_cast<CORBA::Long>(2) != bFU->valLong())) { + ACE_DEBUG( (LM_ERROR, "b is wrong\n") ); testFailed= 1;} + else if ((static_cast<CORBA::Short>(1) != cFU->_d()) || (static_cast<CORBA::Long>(4) != cFU->valLong())) { + ACE_DEBUG( (LM_ERROR, "c is wrong\n") ); testFailed= 1;} + else if ((static_cast<CORBA::Short>(1) != rFU->_d()) || (static_cast<CORBA::Long>(7) != rFU->valLong())) { + ACE_DEBUG( (LM_ERROR, "r is wrong\n") ); testFailed= 1;} + else + ACE_DEBUG( (LM_INFO, "OK\n") ); + + //----------------------------------------------------------------------- + ::Test::MyVarUnion_var + aVU= new ::Test::MyVarUnion(), + bVU, + cVU= new ::Test::MyVarUnion(), + rVU; + aVU->valLong( static_cast<CORBA::Long>(1) ); + cVU->valLong( static_cast<CORBA::Long>(3) ); + ACE_DEBUG( (LM_INFO, ". MyVarUnion() ") ); + rVU= foo->TestVarUnion( aVU, bVU, cVU ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG( (LM_INFO, "a is ") ); + if (static_cast<CORBA::Short>(1) != aVU->_d()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", aVU->valLong()) ); + ACE_DEBUG( (LM_INFO, ", b is ") ); + if (static_cast<CORBA::Short>(1) != bVU->_d()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", bVU->valLong()) ); + ACE_DEBUG( (LM_INFO, ", c is ") ); + if (static_cast<CORBA::Short>(1) != cVU->_d()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", cVU->valLong()) ); + ACE_DEBUG( (LM_INFO, ", r is ") ); + if (static_cast<CORBA::Short>(1) != rVU->_d()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", rVU->valLong()) ); + ACE_DEBUG( (LM_INFO, ": ") ); + if ((static_cast<CORBA::Short>(1) != aVU->_d()) || (static_cast<CORBA::Long>(1) != aVU->valLong())) { + ACE_DEBUG( (LM_ERROR, "a is wrong\n") ); testFailed= 1;} + else if ((static_cast<CORBA::Short>(1) != bVU->_d()) || (static_cast<CORBA::Long>(2) != bVU->valLong())) { + ACE_DEBUG( (LM_ERROR, "b is wrong\n") ); testFailed= 1;} + else if ((static_cast<CORBA::Short>(1) != cVU->_d()) || (static_cast<CORBA::Long>(4) != cVU->valLong())) { + ACE_DEBUG( (LM_ERROR, "c is wrong\n") ); testFailed= 1;} + else if ((static_cast<CORBA::Short>(1) != rVU->_d()) || (static_cast<CORBA::Long>(7) != rVU->valLong())) { + ACE_DEBUG( (LM_ERROR, "r is wrong\n") ); testFailed= 1;} + else + ACE_DEBUG( (LM_INFO, "OK\n") ); + + //----------------------------------------------------------------------- + ::Test::MySeqOfLong_var + aSL= new ::Test::MySeqOfLong(1), + bSL, + cSL= new ::Test::MySeqOfLong(1), + rSL; + aSL->length(1); + aSL[0]= static_cast<CORBA::Long>(1); + cSL->length(1); + cSL[0]= static_cast<CORBA::Long>(3); + ACE_DEBUG( (LM_INFO, ". MySeqOfLong() ") ); + rSL= foo->TestSeqOfLong( aSL, bSL, cSL ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_DEBUG( (LM_INFO, "a is ") ); + if (1u != aSL->length()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", aSL[0]) ); + ACE_DEBUG( (LM_INFO, ", b is ") ); + if (1u != bSL->length()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", bSL[0]) ); + ACE_DEBUG( (LM_INFO, ", c is ") ); + if (1u != cSL->length()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", cSL[0]) ); + ACE_DEBUG( (LM_INFO, ", r is ") ); + if (1u != rSL->length()) + ACE_DEBUG( (LM_INFO, "?") ); + else + ACE_DEBUG( (LM_INFO, "%d", rSL[0]) ); + ACE_DEBUG( (LM_INFO, ": ") ); + if ((1u != aSL->length()) || (static_cast<CORBA::Long>(1) != aSL[0])) { + ACE_DEBUG( (LM_ERROR, "a is wrong\n") ); testFailed= 1;} + else if ((1u != bSL->length()) || (static_cast<CORBA::Long>(2) != bSL[0])) { + ACE_DEBUG( (LM_ERROR, "b is wrong\n") ); testFailed= 1;} + else if ((1u != cSL->length()) || (static_cast<CORBA::Long>(4) != cSL[0])) { + ACE_DEBUG( (LM_ERROR, "c is wrong\n") ); testFailed= 1;} + else if ((1u != rSL->length()) || (static_cast<CORBA::Long>(7) != rSL[0])) { + ACE_DEBUG( (LM_ERROR, "r is wrong\n") ); testFailed= 1;} + else + ACE_DEBUG( (LM_INFO, "OK\n") ); + + //----------------------------------------------------------------------- + ::CORBA::Any_var + aA= new ::CORBA::Any(), + bA, + cA= new ::CORBA::Any(), + rA; + aA<<= static_cast<CORBA::Long>(1); + cA<<= static_cast<CORBA::Long>(3); + ACE_DEBUG( (LM_INFO, ". Any() ") ); + rA= foo->TestAny( aA.in(), bA, cA.inout() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + ::CORBA::Boolean + aB, + bB, + cB, + rB; + ACE_DEBUG( (LM_INFO, "a is ") ); + if (aB= (aA>>= aL)) + ACE_DEBUG( (LM_INFO, "%d", aL) ); + else + ACE_DEBUG( (LM_INFO, "?") ); + ACE_DEBUG( (LM_INFO, ", b is ") ); + if (bB= (bA>>= bL)) + ACE_DEBUG( (LM_INFO, "%d", bL) ); + else + ACE_DEBUG( (LM_INFO, "?") ); + ACE_DEBUG( (LM_INFO, ", c is ") ); + if (cB= (cA>>= cL)) + ACE_DEBUG( (LM_INFO, "%d", cL) ); + else + ACE_DEBUG( (LM_INFO, "?") ); + ACE_DEBUG( (LM_INFO, ", r is ") ); + if (rB= (rA>>= rL)) + ACE_DEBUG( (LM_INFO, "%d", rL) ); + else + ACE_DEBUG( (LM_INFO, "?") ); + ACE_DEBUG( (LM_INFO, ": ") ); + if (!aB || (static_cast<CORBA::Long>(1) != aL)) { + ACE_DEBUG( (LM_ERROR, "a is wrong\n") ); testFailed= 1;} + else if (!bB || (static_cast<CORBA::Long>(2) != bL)) { + ACE_DEBUG( (LM_ERROR, "b is wrong\n") ); testFailed= 1;} + else if (!cB || (static_cast<CORBA::Long>(4) != cL)) { + ACE_DEBUG( (LM_ERROR, "c is wrong\n") ); testFailed= 1;} + else if (!rB || (static_cast<CORBA::Long>(7) != rL)) { + ACE_DEBUG( (LM_ERROR, "r is wrong\n") ); testFailed= 1;} + else + ACE_DEBUG( (LM_INFO, "OK\n") ); + + //----------------------------------------------------------------------- + foo->ShutdownServer( ACE_ENV_SINGLE_ARG_PARAMETER ); + ACE_TRY_CHECK; + + //----------------------------------------------------------------------- + orb->shutdown( true ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + orb->destroy( ACE_ENV_SINGLE_ARG_PARAMETER ); + ACE_TRY_CHECK; + } + ACE_CATCH( CORBA::SystemException, ex ) + { + ACE_PRINT_EXCEPTION( ex, "CORBA::SystemException: " ); + testFailed= 1; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION( ACE_ANY_EXCEPTION, "CORBA::Exception: " ); + testFailed= 1; + } + ACE_CATCHALL + { + ACE_DEBUG( (LM_ERROR, "Unexpected general exception!\n") ); + testFailed= 1; + } + ACE_ENDTRY; + + ACE_DEBUG( (LM_INFO, "Regression test for Bug 2234 ") ); + if (testFailed) + ACE_DEBUG( (LM_ERROR, "Failed\n") ); + else + ACE_DEBUG( (LM_INFO, "Passed\n") ); + + return testFailed? -1 : 0; +} diff --git a/TAO/tests/Bug_2234_Regression/run_test.pl b/TAO/tests/Bug_2234_Regression/run_test.pl new file mode 100755 index 00000000000..41e141ec41d --- /dev/null +++ b/TAO/tests/Bug_2234_Regression/run_test.pl @@ -0,0 +1,48 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ + +# -*- perl -*- + +use lib '../../../bin'; +use PerlACE::Run_Test; + +# The server IOR file +$server_ior_file= PerlACE::LocalFile( "server.ior" ); +unlink $server_ior_file; + +# The client and server processes +$SERVER= new PerlACE::Process( PerlACE::LocalFile( "server" ) ); +$CLIENT= new PerlACE::Process( PerlACE::LocalFile( "client" ) ); + + +# Fire up the server +$SERVER->Spawn(); + +# We can wait on the IOR file +if (PerlACE::waitforfile_timed( $server_ior_file, 10 ) == -1) +{ + print STDERR "ERROR: cannot find $server_ior_file\n"; + $SERVER->Kill(); + exit 1; +} + +if ($CLIENT->SpawnWaitKill( 30 ) != 0) +{ + unlink $server_ior_file; + print STDERR "ERROR: Bug #2234 Regression test failed: cannot run client.\n"; + $SERVER->Kill(); + exit 1; +} +unlink $server_ior_file; + +if ($SERVER->WaitKill( 1 ) != 0) +{ + print STDERR "ERROR: Bug #2234 Regression test failed: server not exiting.\n"; + exit 1; +} + +print STDOUT "Bug #2234 Regression test succeeded.\n"; +exit 0; diff --git a/TAO/tests/Bug_2234_Regression/server.cpp b/TAO/tests/Bug_2234_Regression/server.cpp new file mode 100644 index 00000000000..1c743b43198 --- /dev/null +++ b/TAO/tests/Bug_2234_Regression/server.cpp @@ -0,0 +1,748 @@ +// $Id$ + +// Regression test Bug 2234 +// +// The bug actually manifested itself in class AnInterceptor::receive_request() +// where any OUT parameters of variable length items (as they are held as +// addresses of NULL pointers) +// +// The bug is caused by the arguments() call which should be +// creating a read-only COPY of the parameters to the call. These are held as +// a sequence of ANYs, whith the code for the insertion into which is created +// by the TAO_IDL compiler when their user types are compiled. +// It is also manifested by the result() call in the same way. + +#include "TestS.h" +#include "ace/IOStream.h" +#include "tao/PI/PI.h" +#include "tao/PI_Server/PI_Server.h" +#include "tao/ORBInitializer_Registry.h" +#include "tao/PortableServer/Root_POA.h" + +CORBA::ORB_ptr orb; + +// The test case code for the server always sends back to the client: +// b(out)= a(in) *2 +// c(inout)= c(inout) + 1 +// return= 7 +// Strings are single numerical digits, longs are the numbers themselves +// and sequences are always single long values. +// Parameter 'a' must be received from the client as 1, and 'c' as 3. + +class FooImpl : public POA_Test::Foo +{ +public: + FooImpl() {} + ~FooImpl() {} + + //----------------------------------------------------------- + + CORBA::Long TestLong( + ::CORBA::Long a, + ::CORBA::Long_out b, + ::CORBA::Long &c + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (::CORBA::SystemException ) ) + { + ACE_DEBUG( (LM_INFO, ". in TestLong\n") ); + if (static_cast<CORBA::Long>( 1 ) != a) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + if (static_cast<CORBA::Long>( 3 ) != c) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + + b= static_cast<CORBA::Long>( a << 1 ); + + c+= static_cast<CORBA::Long>( 1 ); + return static_cast<CORBA::Long>( 7 ); + } + + //----------------------------------------------------------- + + char *TestString( + const char *a, + CORBA::String_out b, + char *&c + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (::CORBA::SystemException) ) + { + ACE_DEBUG( (LM_INFO, ". in TestString\n") ); + if (0 == a) + { + ACE_DEBUG( (LM_INFO, "* Incorrect NULL string given for parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if (1 != ACE_OS::strlen( a )) + { + ACE_DEBUG( (LM_INFO, "* Incorrect string length for parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if ('1' != *a) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if (1 != ACE_OS::strlen( c )) + { + ACE_DEBUG( (LM_INFO, "* Incorrect string length for parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if (0 == c) + { + ACE_DEBUG( (LM_INFO, "* Incorrect NULL string given for parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if ('3' != *c) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + + b= CORBA::string_dup( "0" ); // Create a one character output buffer + *b= a[0] + 1; + *c+= 1; + return CORBA::string_dup( "7" ); + } + + //----------------------------------------------------------- + + ::Test::MyNonVarStruct TestNonVarStruct( + const ::Test::MyNonVarStruct &a, + ::Test::MyNonVarStruct_out b, + ::Test::MyNonVarStruct &c + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (::CORBA::SystemException) ) + { + ::Test::MyNonVarStruct + newret; + + ACE_DEBUG( (LM_INFO, ". in TestNonVarStruct\n") ); + if (static_cast<CORBA::Long>( 1 ) != a.val) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), newret ); + } + if (static_cast<CORBA::Long>( 3 ) != c.val) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), newret ); + } + + newret.val= static_cast<CORBA::Long>( 7 ); + + ::Test::MyNonVarStruct *newval_p; + ACE_NEW_RETURN( newval_p, ::Test::MyNonVarStruct(), newret ); + ::Test::MyNonVarStruct_var + newval= newval_p; + + newval->val= a.val << 1; + c.val+= 1; + + b= newval._retn(); + return newret; + } + + //----------------------------------------------------------- + + ::Test::MyVarStruct *TestVarStruct( + const ::Test::MyVarStruct &a, + ::Test::MyVarStruct_out b, + ::Test::MyVarStruct &c + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC(( ::CORBA::SystemException )) + { + ACE_DEBUG( (LM_INFO, ". in TestVarStruct\n") ); + if (0 == a.val.in()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect NULL string given for parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if (1 != ACE_OS::strlen( a.val.in() )) + { + ACE_DEBUG( (LM_INFO, "* Incorrect string length for parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if ('1' != *a.val.in()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if (0 == c.val.in()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect NULL string given for parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if (1 != ACE_OS::strlen( c.val.in() )) + { + ACE_DEBUG( (LM_INFO, "* Incorrect string length for parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + if ('3' != *c.val.in()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0); + } + + char ca[2]= {0}; + ca[0]= ('0' + ((*a.val.in() -'0') << 1)); + + ::Test::MyVarStruct_var + newval_p, + newret_p; + ACE_NEW_RETURN( newval_p, ::Test::MyVarStruct(), 0 ); + ::Test::MyVarStruct_var + newval= newval_p; + ACE_NEW_RETURN( newret_p, ::Test::MyVarStruct(), 0 ); + ::Test::MyVarStruct_var + newret= newret_p; + + newval->val= CORBA::string_dup( ca ); + + *c.val.inout()+= 1; + + newret->val= CORBA::string_dup( "7" ); + + b= newval._retn(); + return newret._retn(); + } + + //----------------------------------------------------------- + + ::Test::MyNonVarUnion TestNonVarUnion( + const ::Test::MyNonVarUnion &a, + ::Test::MyNonVarUnion_out b, + ::Test::MyNonVarUnion &c + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (::CORBA::SystemException) ) + { + ::Test::MyNonVarUnion + newret; + + ACE_DEBUG( (LM_INFO, ". in TestNonVarUnion\n") ); + if (static_cast<CORBA::Short>( 1 ) != a._d()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect type of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), newret ); + } + if (static_cast<CORBA::Long>( 1 ) != a.valLong()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), newret ); + } + if (static_cast<CORBA::Short>( 1 ) != c._d()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect type of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), newret ); + } + if (static_cast<CORBA::Long>( 3 ) != c.valLong()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), newret ); + } + + ::Test::MyNonVarUnion *newval_p; + ACE_NEW_RETURN( newval_p, ::Test::MyNonVarUnion(), newret ); + ::Test::MyNonVarUnion_var + newval= newval_p; + + newval->valLong( a.valLong() << 1 ); + c.valLong( c.valLong() + 1 ); + + newret.valLong( static_cast<CORBA::Long>( 7 ) ); + + b= newval._retn(); + return newret; + } + + //----------------------------------------------------------- + + ::Test::MyVarUnion *TestVarUnion( + const ::Test::MyVarUnion &a, + ::Test::MyVarUnion_out b, + ::Test::MyVarUnion &c + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC (( ::CORBA::SystemException )) + { + ACE_DEBUG( (LM_INFO, ". in TestVarUnion\n") ); + if (static_cast<CORBA::Short>( 1 ) != a._d()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect type of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + if (static_cast<CORBA::Long>( 1 ) != a.valLong()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + if (static_cast<CORBA::Short>( 1 ) != c._d()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect type of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + if (static_cast<CORBA::Long>( 3 ) != c.valLong()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + + ::Test::MyVarUnion *newval_p; + ACE_NEW_RETURN( newval_p, ::Test::MyVarUnion(), 0 ); + ::Test::MyVarUnion_var + newval= newval_p; + + newval->valLong( a.valLong() << 1 ); + c.valLong( c.valLong() + 1 ); + + ::Test::MyVarUnion_var + newret_p; + ACE_NEW_RETURN( newret_p, ::Test::MyVarUnion(), 0 ); + ::Test::MyVarUnion_var + newret= newret_p; + newret->valLong( static_cast<CORBA::Short>( 7 ) ); + + b= newval._retn(); + return newret._retn(); + } + + //----------------------------------------------------------- + + ::Test::MySeqOfLong *TestSeqOfLong ( + const ::Test::MySeqOfLong &a, + ::Test::MySeqOfLong_out b, + ::Test::MySeqOfLong &c + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (::CORBA::SystemException) ) + { + ACE_DEBUG( (LM_INFO, ". in TestSeqOfLong\n") ); + if (1u != a.length()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect length of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + if (static_cast<CORBA::Long>( 1 ) != a[0]) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + if (1u != c.length()) + { + ACE_DEBUG( (LM_INFO, "* Incorrect length of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + if (static_cast<CORBA::Long>( 3 ) != c[0]) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + + ::Test::MySeqOfLong *newval_p; + ACE_NEW_RETURN( newval_p, ::Test::MySeqOfLong(1), 0 ); + ::Test::MySeqOfLong_var + newval= newval_p; + + newval->length(1); + newval[0]= a[0] << 1; + c[0]+= 1; + + ::Test::MySeqOfLong *newret_p; + ACE_NEW_RETURN( newret_p, ::Test::MySeqOfLong(1), 0 ); + ::Test::MySeqOfLong_var + newret= newret_p; + newret->length( 1 ); + newret[0]= static_cast<CORBA::Long>( 7 ); + + b= newval._retn(); + return newret._retn(); + } + + //----------------------------------------------------------- + + CORBA::Any *TestAny( + const ::CORBA::Any &a, + ::CORBA::Any_out b, + ::CORBA::Any &c + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException) ) + { + ACE_DEBUG( (LM_INFO, ". in TestAny\n") ); + CORBA::Long aL; + CORBA::Long cL; + if (a >>= aL) + { + if (static_cast<CORBA::Long>( 1 ) != aL) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + } + else + { + ACE_DEBUG( (LM_INFO, "* Incorrect any type for parameter a\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + if (c >>= cL) + { + if (static_cast<CORBA::Long>( 3 ) != cL) + { + ACE_DEBUG( (LM_INFO, "* Incorrect input value of parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + } + else + { + ACE_DEBUG( (LM_INFO, "* Incorrect any type for parameter c\n") ); + ACE_THROW_RETURN( ::CORBA::BAD_PARAM(0, ::CORBA::COMPLETED_NO), 0 ); + } + + ::CORBA::Any *newval_p; + ACE_NEW_RETURN( newval_p, ::CORBA::Any(), 0 ); + ::CORBA::Any_var + newval= newval_p; + + newval<<= aL << 1; + c<<= cL + 1; + + ::CORBA::Any *newret_p; + ACE_NEW_RETURN( newret_p, ::CORBA::Any(), 0 ); + ::CORBA::Any_var + newret= newret_p; + newret<<= static_cast<CORBA::Long>( 7 ); + + b= newval._retn(); + return newret._retn(); + } + + //----------------------------------------------------------- + + void ShutdownServer( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException) ) + { + ACE_DEBUG( (LM_INFO, ". in ShutdownServer\n") ); + orb->shutdown(0 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +}; + +// Here is our Regression test class that actually tests the problem with +// the interceptor's arguments. + +class AnInterceptor : public PortableInterceptor::ServerRequestInterceptor +{ +public: + char *name( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException) ) + { + return const_cast<char *>(""); + } + + void destroy( ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException) ) + { + } + + void receive_request_service_contexts( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException, + PortableInterceptor::ForwardRequest) ) + { + } + + // Note this helper only deals with the types inserted into + // the any that we defined for this test. + static void display_any( const CORBA::Any &arg ) + { + const CORBA::Any *holding; + const ::Test::MyVarStruct *vS; + const ::Test::MyNonVarStruct *fS; + const char *pString; + ::CORBA::Long theLong; + const ::Test::MyVarUnion *vU; + const ::Test::MyNonVarUnion *fU; + const ::Test::MySeqOfLong *sL; + + if (arg >>= vS) + { + ACE_DEBUG( (LM_INFO, "MyVarStruct (") ); + if (vS) + ACE_DEBUG( (LM_INFO, vS->val.in()) ); + else + ACE_DEBUG( (LM_INFO, "*Null*") ); + } + else if (arg >>= fS) + { + ACE_DEBUG( (LM_INFO, "MyNonVarStruct (") ); + if (fS) + ACE_DEBUG( (LM_INFO, "%d", fS->val) ); + else + ACE_DEBUG( (LM_INFO, "*Null*") ); + } + else if (arg >>= pString) + { + ACE_DEBUG( (LM_INFO, "String (") ); + if (pString) + ACE_DEBUG( (LM_INFO, pString) ); + else + ACE_DEBUG( (LM_INFO, "*Null*") ); + } + else if (arg >>= theLong) + ACE_DEBUG( (LM_INFO, "Long (%d", theLong) ); + else if (arg >>= fU) + { + ACE_DEBUG( (LM_INFO, "MyNonVarUnion (") ); + if (fU) switch (fU->_d()) + { + case 1: + ACE_DEBUG( (LM_INFO, "Long %d", fU->valLong()) ); + break; + + case 2: + ACE_DEBUG( (LM_INFO, "Short %d", fU->valShort()) ); + break; + + default: + ACE_DEBUG( (LM_INFO, "*Unknown*") ); + } + else + ACE_DEBUG( (LM_INFO, "*Null*") ); + } + else if (arg >>= vU) + { + ACE_DEBUG( (LM_INFO, "MyVarUnion (") ); + if (vU) switch (vU->_d()) + { + case 1: + ACE_DEBUG( (LM_INFO, "Long %d", vU->valLong()) ); + break; + + case 2: + ACE_DEBUG( (LM_INFO, "String %s", vU->valString()) ); + break; + + default: + ACE_DEBUG( (LM_INFO, "*Unknown*") ); + } + else + ACE_DEBUG( (LM_INFO, "*Null*") ); + } + else if (arg >>= sL) + { + ACE_DEBUG( (LM_INFO, "MySeqOfLong (") ); + if (sL) + { + if (0u < sL->length()) + { + for (unsigned int i= 0u; i < sL->length() - 1u; ++i) + ACE_DEBUG( (LM_INFO, "%d, ", (*sL)[ i ]) ); + ACE_DEBUG( (LM_INFO, "%d", (*sL)[ sL->length() - 1u ]) ); + } + else + ACE_DEBUG( (LM_INFO, "*Empty*") ); + } + else + ACE_DEBUG( (LM_INFO, "*Null*") ); + } + else if (arg >>= holding) + { + ACE_DEBUG( (LM_INFO, "Any (") ); + if (holding) + { + if (*holding >>= theLong) + ACE_DEBUG( (LM_INFO, "Long %d", theLong) ); + else + ACE_DEBUG( (LM_INFO, "*Not Long*") ); + } + else + ACE_DEBUG( (LM_INFO, "*Null*") ); + } + else + ACE_DEBUG( (LM_INFO, "Unknown (") ); + ACE_DEBUG( (LM_INFO, ") parameter\n") ); + } + + // Useful parameter dumping helper method.-----------| Note this VAR + // which will automatically delete after the call! V + static void display_arg_list( Dynamic::ParameterList_var param_list ) + { + for (unsigned int i= 0u; i < param_list->length(); ++i) + { + ACE_DEBUG( (LM_INFO, " param %d is an ", i) ); + switch( (*param_list)[i].mode ) + { + case CORBA::PARAM_IN: + ACE_DEBUG( (LM_INFO, "in ") ); + break; + + case CORBA::PARAM_OUT: + ACE_DEBUG( (LM_INFO, "out ") ); + break; + + case CORBA::PARAM_INOUT: + ACE_DEBUG( (LM_INFO, "inout ") ); + break; + + default: + ACE_DEBUG( (LM_INFO, "non-directional ") ); + break; + } + + display_any( (*param_list)[i].argument ); + } + } + + void receive_request( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException, + PortableInterceptor::ForwardRequest) ) + { + ACE_DEBUG( (LM_INFO, "AnInterceptor::receive_request\n") ); + Dynamic::ParameterList + *pArgs= ri->arguments( ACE_ENV_SINGLE_ARG_PARAMETER ); + ACE_CHECK; + display_arg_list( pArgs ); + } + + // This send_reply() method would cause the problem due to it's + // ri->arguments() call. When the returned arguments list was + // deleted (due to the display_arg_list( Dynamic::ParameterList_var )) + // going out of scope, the "Owned" out pointer 'Argument B' would + // be premiturely deleted before being sent back to the client. + void send_reply( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException) ) + { + ACE_DEBUG( (LM_INFO, "AnInterceptor::send_reply\n") ); + Dynamic::ParameterList + *pArgs= ri->arguments( ACE_ENV_SINGLE_ARG_PARAMETER ); + ACE_CHECK; + display_arg_list( pArgs ); + ACE_DEBUG( (LM_INFO, " result is an ") ); + CORBA::Any + *pAny= ri->result( ACE_ENV_SINGLE_ARG_PARAMETER ); + ACE_CHECK; + display_any( *CORBA::Any_var( pAny ) ); + ACE_DEBUG( (LM_INFO, "\n") ); + } + + void send_exception( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException, + PortableInterceptor::ForwardRequest) ) + { + } + + void send_other( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (CORBA::SystemException, + PortableInterceptor::ForwardRequest) ) + { + } +}; + +class Initialiser : public PortableInterceptor::ORBInitializer +{ +public: + Initialiser( AnInterceptor* interceptor ) + { + this->interceptor= interceptor; + } + + void pre_init( + PortableInterceptor::ORBInitInfo_ptr + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (::CORBA::SystemException) ) + { + } + + void post_init( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS ) + ACE_THROW_SPEC( (::CORBA::SystemException) ) + { + info->add_server_request_interceptor( interceptor ); + } + +private: + AnInterceptor *interceptor; +}; + +int main( int argc, char *argv[] ) +{ + ACE_TRY + { + ACE_DEBUG( (LM_INFO, "Server start\n") ); + AnInterceptor + interceptor; + PortableInterceptor::ORBInitializer_ptr + initialiser_p; + ACE_NEW_RETURN( initialiser_p, Initialiser( &interceptor ), -1 ); + PortableInterceptor::ORBInitializer_var + initialiser= initialiser_p; + PortableInterceptor::register_orb_initializer( initialiser.in() ); + + orb= CORBA::ORB_init( argc, argv ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + CORBA::Object_var + Object = orb->resolve_initial_references( "RootPOA" ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + PortableServer::POA_var rootPOA= + PortableServer::POA::_narrow( Object.in() ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + PortableServer::POAManager_var + rootPOAMgr = rootPOA->the_POAManager( ACE_ENV_SINGLE_ARG_PARAMETER ); + ACE_TRY_CHECK; + + FooImpl + phooey; + PortableServer::ObjectId_var + phooeyId= rootPOA->activate_object( &phooey ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + CORBA::Object_var + phooeyObj= rootPOA->id_to_reference( phooeyId.in() ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + CORBA::String_var + stringifiedObj= orb->object_to_string( phooeyObj.in() ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + ofstream file( "server.ior" ); + file << stringifiedObj; + file.close(); + + rootPOAMgr->activate( ACE_ENV_SINGLE_ARG_PARAMETER ); + ACE_TRY_CHECK; + + orb->run( 0 ACE_ENV_ARG_PARAMETER ); + ACE_TRY_CHECK; + + orb->destroy( ACE_ENV_SINGLE_ARG_PARAMETER ); + ACE_TRY_CHECK; + } + ACE_CATCH( CORBA::SystemException, exception ) + { + ACE_PRINT_EXCEPTION( exception, "CORBA::SystemException: " ); + return -1; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION( ACE_ANY_EXCEPTION, "CORBA::Exception: " ); + return -1; + } + ACE_CATCHALL + { + ACE_DEBUG( (LM_ERROR, "Unexpected general exception.\n") ); + return -1; + } + ACE_ENDTRY; + + ACE_DEBUG( (LM_INFO, "Server stopped\n") ); + return 0; +} |