Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repro problem with fragmented GIOP messages #1205

Merged
merged 7 commits into from
Dec 29, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.obj
.depend.Echo_Client
.depend.Echo_Server
.depend.echo_idl
.depend.echo_idl_Idl1
server_log.txt
client_log.txt
client
server
client_log.txt
server_log.txt
18 changes: 18 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/Echo.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* -*- C++ -*- */
#if !defined (_ECHO_IDL)
#define _ECHO_IDL

interface Echo
{
// = TITLE
// Defines an interface that encapsulates an operation that returns
// a string sequence.

typedef sequence<string> List;

List return_list ();

oneway void shutdown ();
};

#endif /* _ECHO_IDL */
78 changes: 78 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/Echo_Client_i.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "Echo_Client_i.h"
#include "ace/Get_Opt.h"
#include "ace/Read_Buffer.h"
#include "ace/OS_NS_unistd.h"
#include <iostream>
#include <cstring>

// This is the interface program that accesses the remote object

// Constructor.
Echo_Client_i::Echo_Client_i (void)
{
//no-op
}

//Destructor.
Echo_Client_i::~Echo_Client_i (void)
{
//no-op
}

int
Echo_Client_i::run (const char *name,
int argc,
ACE_TCHAR *argv[])
{
// Initialize the client.
if (client_.init (name, argc, argv) == -1)
return -1;

try
{
Echo::List_var list = client_->return_list();
std::cout << "Received list of length "
<< list->length() << std::endl;
if (list->length() != 2)
{
std::cout << "ERROR: Expected length 2, exiting..." << std::endl;
client_->shutdown ();
return -1;
}
const char* value = (*list)[0].in();
size_t length = std::strlen(value);
std::cout << "First element has length "
<< length << std::endl;
for (size_t n = 0; n < length; ++n)
{
if (value[n] != 'A')
{
std::cout << "ERROR: Character at position " << n
<< " should be 'A', but is '"
<< value[n] << "'" << std::endl;
client_->shutdown ();
return -1;
}
}
value = (*list)[1].in();
length = std::strlen(value);
std::cout << "Second element has length "
<< length << std::endl;
std::cout << "Value: " << value << std::endl;
if (std::strcmp(value, "Hello World") != 0)
{
std::cout << "ERROR: Expected \"Hello World\", exiting..."
<< std::endl;
client_->shutdown ();
return -1;
}
client_->shutdown ();
}
catch (const CORBA::Exception& ex)
{
ex._tao_print_exception ("\n Exception in RMI");
return -1;
}

return 0;
}
34 changes: 34 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/Echo_Client_i.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// -*- C++ -*-

#ifndef ECHO_CLIENT_I_H
#define ECHO_CLIENT_I_H

#include "../../../examples/Simple/Simple_util.h"
#include "EchoC.h"

/**
* @class Echo_Client_i
*
* @brief Echo_Client interface subclass.
*
* This class implements the interface between the interface
* objects and the client .
*/
class Echo_Client_i
{
public:
/// Constructor
Echo_Client_i (void);

/// Destructor
~Echo_Client_i (void);

/// Execute the methods
int run (const char *, int, ACE_TCHAR **);

private:
/// Instantiate the client object.
Client<Echo> client_;
};

#endif /* TIME_CLIENT_I_H */
62 changes: 62 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/Echo_i.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <string>
#include "Echo_i.h"

// Constructor.

Echo_i::Echo_i (void)
{
}

// Destructor.

Echo_i::~Echo_i (void)
{
}

// Set the ORB pointer.

void
Echo_i::orb (CORBA::ORB_ptr o)
{
this->orb_ = CORBA::ORB::_duplicate (o);
}

// Return a list of strings.

Echo::List *
Echo_i::return_list ()
{
Echo::List_var list;

{
Echo::List *tmp = 0;
ACE_NEW_RETURN (tmp,
Echo::List (2),
0);
// Pass ownership to the _var, pitty that ACE_NEW_RETURN cannot
// assign to T_vars directly.
list = tmp;
}

list->length (2);

// Just do something to get a 'big' list of strings.
std::string big(4 * 1024 * 1024, 'A');
std::string small("Hello World");
list[CORBA::ULong(0)] = CORBA::string_dup(big.c_str());
list[CORBA::ULong(1)] = CORBA::string_dup(small.c_str());

return list._retn ();
}

// Shutdown the server application.

void
Echo_i::shutdown (void)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("\nThe echo server is shutting down\n")));

// Instruct the ORB to shutdown.
this->orb_->shutdown ();
}
54 changes: 54 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/Echo_i.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// -*- C++ -*-

//=============================================================================
/**
* @file Echo_i.h
*
* This class implements the Echo IDL interface.
*
* @author Kirthika Parameswaran <[email protected]>
*/
//=============================================================================


#ifndef ECHO_I_H
#define ECHO_I_H

#include "EchoS.h"

/**
* @class Echo_i
*
* @brief Echo Object Implementation
*
* The object implementation performs the following functions:
* -- To return the string which needs to be displayed
* from the server.
* -- shuts down the server
*/
class Echo_i : public POA_Echo
{
public:
/// Constructor.
Echo_i (void);

/// Destructor.
virtual ~Echo_i (void);

/// Return the mesg string back from the server.
virtual Echo::List *return_list ();

/// Shutdown the server.
virtual void shutdown ();

/// Set the ORB pointer.
void orb (CORBA::ORB_ptr o);

private:
/// ORB pointer.
CORBA::ORB_var orb_;

void operator= (const Echo_i&);
};

#endif /* ECHO_I_H */
19 changes: 19 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TAO GIOP Fragmentation Bug
## Reproduces a bug when GIOP fragmentation is used

The server returns a string sequence with two elements, the first is a
long 4MB string with repeating character 'A', the second element is
the string "Hello World". If one removes the command line parameters
`-ORBMaxMessageSize 1048576` from `run_test.pl` everything
works as expected, but with these settings, which cause GIOP
fragmentation, the client receives an empty string as the second
element of the sequence.

We discovered problems in a more complicated application when big
sequences are returned, often the client encountering
`CORBA::MARSHAL` or `CORBA::COMM_FAILURE` exceptions. In one
case, it worked if the sequence contained a single element, even if
big, but a small second element caused client exceptions. The complex
application encountered problems with big sequences even without the
`-ORBMaxMessageSize` parameter, but problems start at smaller
sizes if it is used.
19 changes: 19 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# include "Echo_Client_i.h"

// The client program for the application.

int
ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
Echo_Client_i client;

ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("\nEcho client\n\n")));

if (client.run ("Echo",
argc,
argv) == -1)
return -1;
else
return 0;
}
34 changes: 34 additions & 0 deletions TAO/tests/GIOP_Fragments/Big_String_Sequence/echo.mpc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// -*- MPC -*-
project(*idl): taoidldefaults {
IDL_Files {
Echo.idl
}
custom_only = 1
}

project(*Server): taoserver, namingexe, iortable, utils {
exename = server
after += *idl
Source_Files {
Echo_i.cpp
../../../examples/Simple/Simple_util.cpp
server.cpp
EchoS.cpp
EchoC.cpp
}
IDL_Files {
}
}

project(*Client): taoclient, namingexe, iortable, utils {
exename = client
after += *IDL
Source_Files {
Echo_Client_i.cpp
../../../examples/Simple/Simple_util.cpp
client.cpp
EchoC.cpp
}
IDL_Files {
}
}
Loading