[Ace-users] TAO-ORB: Server crashes intermittently on restarts
mak
khan.m.arshad at gmail.com
Mon Jul 16 05:15:12 CDT 2007
TAO VERSION: 1.5.9
ACE VERSION: 5.5.9
HOST MACHINE and OPERATING SYSTEM:
Linux 2.6.20-1.2320.fc5smp #1 SMP i686 i686 i386 GNU/Linux
TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
COMPILER NAME AND VERSION (AND PATCHLEVEL):
g++ (GCC) 4.1.1 20070105 (Red Hat 4.1.1-51)
THE $ACE_ROOT/ace/config.h FILE :
#include "ace/config-linux.h"
THE $ACE_ROOT/include/makeinclude/platform_macros.GNU FILE:
include $(ACE_ROOT)/include/makeinclude/platform_linux.GNU
CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/
default.features
:
AREA/CLASS/EXAMPLE AFFECTED:
ORB
DOES THE PROBLEM AFFECT:
COMPILATION?
"No"
LINKING?
"No"
EXECUTION?
"Yes"
OTHER (please specify)?
SYNOPSIS:
Server crashes intermittently on restarts.
DESCRIPTION:
My application provides Server restart functionality when a
certain
IDL method is called by a remote client. The restart process is
sometimes
successful and sometimes ends in segmentation fault.
The SEGV happens in ORB::run method. The core file indicates
following
place for the crash:
Program terminated with signal 11, Segmentation fault.
#0 0x09e08990 in ?? ()
(gdb) where
#0 0x09e08990 in ?? ()
#1 0x001c5c02 in TAO_ORB_Core::run (this=0x9e08e48, tv=0x0,
perform_work=0)
at /home/akhan/ecp/software/external/acetao/TAO/tao/
LF_Event_Loop_Thread_Helper.inl:24
#2 0x001bfb7c in CORBA::ORB::run (this=0x9df4540, tv=0x0) at ORB.cpp:
202
#3 0x001bfbe5 in CORBA::ORB::run (this=0x9df4540) at ORB.cpp:188
#4 0x080501dd in RestartTestTPWorker::svc (this=0x9dfed40) at
RestartTestRunner.cpp:250
#5 0x008d3e56 in ACE_Task_Base::svc_run (args=0x9dfed40) at Task.cpp:
271
#6 0x008d4818 in ACE_Thread_Adapter::invoke_i (this=0x9e153f8) at
Thread_Adapter.cpp:146
#7 0x008d49e6 in ACE_Thread_Adapter::invoke (this=0x9e153f8) at
Thread_Adapter.cpp:95
#8 0x008693d1 in ace_thread_adapter (args=0x9e153f8) at
Base_Thread_Adapter.cpp:116
#9 0x00db3433 in start_thread () from /lib/libpthread.so.0
#10 0x00c0ba1e in clone () from /lib/libc.so.6
(gdb)
It could be something that I'm doing wrong. I have my suspicion on
the
way I reset reactor event loop on restart. Any help is very much
appreciated.
Thanks
Arshad
REPEAT BY:
Test case follows. Apologies for a rather long test case.:(. Please
let
me know if there are any questions about the test case.
The files are:
1. RestartTest.idl: Interface definition.
2. RestartTestIntf_i.h|cpp : CORBA servant implementing the IDL
interface.
3. RestartTestRunner.h|cpp : Class containing ORB initialize and
shutdown methods.
Also contains class for ORB Thread Pool
Worker.
4. server.cpp : Server main. Also contains Signal handler class to
handle
SIGINT.
5. client.cpp : Client main.
How to build:
1. Generate make files.
$ACE_ROOT/bin/mwc.pl -type gnuace restart.mwc
2. Do the make
make
How to run:
1. Run the server (make sure port 1234 is available)
./server -ORBEndPoint iiop://localhost:1234
2. Run the client
./client -ORBInitRef Test=corbaloc::localhost:1234/Test
Expected Result:
"The server should restart successfully on multiple invocation of the
client."
Observed Result:
"The server restarts but gets a segmentation fault after a few client
invocations."
----- File: RestartTest.idl -----
module RestartTest {
/**
* Restart Test interface.
*/
interface RestartTestIntf {
/**
* A two way method to exercise the server.
*/
string test_echo_string(in string message);
/**
* Restarts the server.
*/
oneway void test_restart();
/**
* Shutsdown the server.
*/
oneway void test_shutdown();
};
};
-------------------------------------
----- File: RestartTestIntf_i.h -----
#ifndef RESTART_TEST_INTF_I_H
#define RESTART_TEST_INTF_I_H
#include /**/ "ace/pre.h"
#include "RestartTestS.h"
class RestartTestIntf_i :
public virtual POA_RestartTest::RestartTestIntf
{
public:
/**
* Constructor.
*/
RestartTestIntf_i() {}
/**
* Destructor
*/
~RestartTestIntf_i() {}
/**
* A two way method to exercise the server.
* @param value Passed in string.
* @return Returns back the passed in string.
*/
virtual char * test_echo_string(const char * value);
/**
* Restarts the server.
*/
virtual void test_restart();
/**
* Shutsdown the server.
*/
virtual void test_shutdown();
};
#include /**/ "ace/post.h"
#endif /* RESTART_TEST_INTF_I_H */
-------------------------------------
----- File: RestartTestIntf_i.cpp -----
#include "RestartTestIntf_i.h"
#include "RestartTestRunner.h"
#include "ace/Signal.h"
//X//////////////////////X////////////////////
X//////////////////////////
//
// test_echo_string
//X//////////////////////X////////////////////
X//////////////////////////
char *
RestartTestIntf_i::test_echo_string(const char * value)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) RestartTestIntf_i::test_echo_string.\n"));
char * retVal = CORBA::string_dup(value);
return retVal;
}
//X//////////////////////X////////////////////
X//////////////////////////
//
// test_restart
//X//////////////////////X////////////////////
X//////////////////////////
void
RestartTestIntf_i::test_restart()
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) RestartTestIntf_i::test_restart.\n"));
// Set the restart flag to true so that main method can
// re-init the RestartTestRunner.
RestartTestRunner::mRestart = true;
// Send a SIGINT signal to the signal handler for
// shutdown (and then a restart)
ACE_OS::kill(ACE_OS::getpid(), SIGINT);
}
//X//////////////////////X////////////////////
X//////////////////////////
//
// test_shutdown
//X//////////////////////X////////////////////
X//////////////////////////
void
RestartTestIntf_i::test_shutdown()
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) RestartTestIntf_i::test_shutdown.\n"));
// Set the restart flag to true so that main method can
// does not restarts the server.
RestartTestRunner::mRestart = false;
// Send a SIGINT signal to the signal handler for
// shutdown.
ACE_OS::kill(ACE_OS::getpid(), SIGINT);
}
-------------------------------------
----- File: RestartTestRunner.h -----
#ifndef RESTART_TEST_RUNNER_H
#define RESTART_TEST_RUNNER_H
#include /**/ "ace/pre.h"
#include "ace/Task.h"
#include "tao/ORB.h"
#include "tao/PortableServer/PortableServer.h"
// Flag to conditionally compile TAO Singleton Manager's Initialize
// and finalization.
#define DO_SING_MGR_INIT_FINI 1
/**
* Thread Pool worker class.
*
* Objects of this class represent a thread pool worker. Each worker
* executes the orb->run method and services incoming requests.
*/
class RestartTestTPWorker : public ACE_Task_Base {
private:
/// An initialized ORB instance.
CORBA::ORB_var pOrb;
public:
/**
* Constructor
*/
RestartTestTPWorker (CORBA::ORB_ptr orb);
/**
* Destructor
*/
virtual ~RestartTestTPWorker();
/**
* Thread svc method.
*/
virtual int svc(void);
}; /* RestartTestTPWorker */
/**
* Class that initializes the ORB and POAs and instantiate
* thread pool workers.
*/
class RestartTestRunner {
private:
/// Command line arguments.
int mArgc;
char **pArgv;
/// ORB instance.
CORBA::ORB_var pOrb;
/// POA instance for servicing rqeuests.
PortableServer::POA_var pTestPOA;
/// Thread Pool worker instance.
RestartTestTPWorker * pWorkers;
/// Flag indicating if the ORB is initialized successfully.
bool mInited;
public:
/// Flag used for indicating whether a restart is needed.
static bool mRestart;
/**
* Constructor
*/
RestartTestRunner (int argc, char *argv[]);
/**
* Destructor
*/
virtual ~RestartTestRunner();
/**
* Initializes ORB and POAs.
*/
virtual int initialize(void);
/**
* Shuts down the ORB.
*/
virtual int shutdown();
};
#include /**/ "ace/post.h"
#endif /* RestartTestRunner */
-------------------------------------
----- File: RestartTestRunner.cpp -----
#include "RestartTestRunner.h"
#include "RestartTestIntf_i.h"
#include "ace/ARGV.h"
#include "tao/Object.h"
#include "tao/IORTable/IORTable.h"
#include "tao/TAO_Singleton_Manager.h"
// Public fields and methods for RestartTestRunner.
bool RestartTestRunner::mRestart = false;
//X//////////////////////X////////////////////
X//////////////////////////
//
// Constructor
//X//////////////////////X////////////////////
X//////////////////////////
RestartTestRunner::RestartTestRunner(int argc, char *argv[])
: mArgc(argc),
pArgv(argv),
pOrb(CORBA::ORB::_nil()),
pWorkers(0),
mInited(false)
{
}
//X//////////////////////X////////////////////
X//////////////////////////
//
// Destructor
//X//////////////////////X////////////////////
X//////////////////////////
RestartTestRunner::~RestartTestRunner()
{
if (mInited)
{
mInited = false;
this->shutdown();
}
if (pWorkers)
{
delete pWorkers;
pWorkers = 0;
}
}
//X//////////////////////X////////////////////
X//////////////////////////
//
// initialize
//X//////////////////////X////////////////////
X//////////////////////////
int
RestartTestRunner::initialize(void)
{
try
{
#ifdef DO_SING_MGR_INIT_FINI
int register_with_object_manager = 0;
if (TAO_Singleton_Manager::instance ()->init (
register_with_object_manager) == -1)
{
ACE_DEBUG ((LM_ERROR,
"(%P|%t) RestartTestRunner - initialize: ",
"Failed to initialize TAO Singleton Manager.
\n"));
return -1;
}
#endif
// Copy command line arguments and pass them to ORB_init
ACE_ARGV newArgs(pArgv);
pOrb = CORBA::ORB_init(mArgc,newArgs.argv());
// Get RootPOA
CORBA::Object_var obj = pOrb-
>resolve_initial_references("RootPOA");
PortableServer::POA_var rootPOA =
PortableServer::POA::_narrow(obj.in());
// Create Persistent Object Lifespan policy
PortableServer::LifespanPolicy_var persistentLifespan =
rootPOA-
>create_lifespan_policy(
PortableServer::PERSISTENT);
// Create User assigned Id policy
PortableServer::IdAssignmentPolicy_var idAssign =
rootPOA-
>create_id_assignment_policy(
PortableServer::USER_ID);
CORBA::PolicyList persistentPOAPolicy (2);
persistentPOAPolicy.length (2);
persistentPOAPolicy[0] =
PortableServer::LifespanPolicy::_duplicate(persistentLifespan);
persistentPOAPolicy[1] =
PortableServer::IdAssignmentPolicy::_duplicate(idAssign);
// Create POA with Persistent lifespan and User assigned Id
policies
// and its own POAManager
pTestPOA = rootPOA->create_POA("TestPOA",
PortableServer::POAManager::_nil(),
persistentPOAPolicy);
// Create the servant.
RestartTestIntf_i * pServant = new RestartTestIntf_i();
PortableServer::ObjectId_var oid =
PortableServer::string_to_ObjectId("Test");
/// Activate the object
pTestPOA->activate_object_with_id(oid, pServant);
CORBA::Object_var testObj = pTestPOA-
>servant_to_reference(pServant);
CORBA::String_var iorStr = pOrb-
>object_to_string(testObj.in());
// Bind this object reference in the IORTable with an alias
CORBA::Object_var iorTabObj =
pOrb-
>resolve_initial_references("IORTable");
IORTable::Table_var iorTab =
IORTable::Table::_narrow(iorTabObj.in());
iorTab->bind ("Test", iorStr.in ());
// Activate POAs
PortableServer::POAManager_var pmgr1 = rootPOA-
>the_POAManager();
pmgr1->activate();
PortableServer::POAManager_var pmgr2 = pTestPOA-
>the_POAManager();
pmgr2->activate();
// Destroy the policy object
persistentLifespan->destroy();
idAssign->destroy();
// Now create ThreadPool workers and activate them
pWorkers = new RestartTestTPWorker(pOrb.in());
if (pWorkers->activate(THR_NEW_LWP | THR_JOINABLE,2) == -1)
{
pOrb->destroy();
ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t) RestartTestRunner - initialize:
"
"Failed to activate Pool Workers.\n"),
-1);
}
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) RestartTestRunner::initialize: Success.
\n"));
mInited = true;
}
catch (const CORBA::Exception & e)
{
ACE_DEBUG ((LM_ERROR,
"(%P|%t) RestartTestRunner::initialize: "
"CORBA Exception caught while initializing: "));
e._tao_print_exception("\n");
return -1;
}
return 0;
}
//X//////////////////////X////////////////////
X//////////////////////////
//
// shutdown
//X//////////////////////X////////////////////
X//////////////////////////
int
RestartTestRunner::shutdown()
{
try
{
// Do an ORB shutdown.
pOrb->shutdown(1);
// Wait for all pool workers to finish.
pWorkers->wait();
mInited = false;
#ifdef DO_SING_MGR_INIT_FINI
if (TAO_Singleton_Manager::instance ()->fini () == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t) RestartTestRunner::shutdown: ",
"Failed to finalize TAO Singleton
Manager.\n"),
-1);
}
#endif
ACE_DEBUG ((LM_INFO,
"(%P|%t) RestartTestRunner::shutdown: "
"ORB shutdown successful.\n"));
}
catch (const CORBA::Exception& e)
{
ACE_DEBUG ((LM_ERROR,
"(%P|%t) RestartTestRunner::shutdown: "
"CORBA Exception caught while shutting down: "));
e._tao_print_exception("\n");
return -1;
}
return 0;
}
// Public fields and methods for RestartTestTPWorker.
//X//////////////////////X////////////////////
X//////////////////////////
//
// Constructor
//X//////////////////////X////////////////////
X//////////////////////////
RestartTestTPWorker::RestartTestTPWorker(CORBA::ORB_ptr orb)
: pOrb(CORBA::ORB::_duplicate(orb))
{
}
//X//////////////////////X////////////////////
X//////////////////////////
//
// Destructor
//X//////////////////////X////////////////////
X//////////////////////////
RestartTestTPWorker::~RestartTestTPWorker()
{
}
//X//////////////////////X////////////////////
X//////////////////////////
//
// svc
//X//////////////////////X////////////////////
X//////////////////////////
int
RestartTestTPWorker::svc()
{
try
{
pOrb->run();
}
catch (const CORBA::Exception& e)
{
ACE_DEBUG ((LM_ERROR,
"(%P|%t) RestartTestTPWorker - svc: ",
"CORBA Exception caught while in orb->run: "));
e._tao_print_exception("\n");
return -1;
}
catch (...)
{
ACE_ERROR_RETURN((LM_ERROR,
"(%P|%t) RestartTestTPWorker - svc: ",
"Exception caught while in orb->run"),
-1);
}
return 0;
}
-------------------------------------
----- File: server.cpp -----
#include "RestartTestRunner.h"
#include "ace/Reactor.h"
#include "ace/Signal.h"
/**
* Class for doing signal handling.
*/
class SigHandler : public ACE_Event_Handler {
private:
/// Pointer to the test runner
RestartTestRunner * pRunner;
public:
SigHandler(RestartTestRunner * runner) :
pRunner(runner) {}
~SigHandler() {}
int handle_signal(int signum, siginfo_t * =0, ucontext_t * =0)
{
switch (signum)
{
case SIGINT:
try
{
pRunner->shutdown();
ACE_Reactor::instance()-
>end_reactor_event_loop();
}
catch(...)
{
ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t)
SigHandler::handle_signal"),
-1);
};
break;
default:
break;
}
return 0;
}
};
int main(int argc, char* argv[])
{
bool restart = false;
do
{
if (restart)
{
ACE_DEBUG ((LM_INFO,
"(%P|%t) server::main: ",
"Restarting Server.\n"));
RestartTestRunner::mRestart = false;
}
RestartTestRunner * pRunner = new RestartTestRunner(argc,
argv);
if (pRunner->initialize() == -1)
{
ACE_DEBUG ((LM_ERROR,
"(%P|%t) server::main: "
"Error while initializing Test Runner.\n"));
return -1;
}
if (restart)
{
ACE_DEBUG ((LM_INFO,
"(%P|%t) server::main: Server Re-started.
\n"));
}
else
{
ACE_DEBUG ((LM_INFO,
"(%P|%t) server::main: Server Started.
\n"));
}
ACE_Sig_Set signalSet;
signalSet.sig_add( SIGINT );
SigHandler handler(pRunner);
ACE_Reactor::instance()->register_handler( signalSet,
&handler );
ACE_Reactor::instance()->run_reactor_event_loop();
ACE_Reactor::instance()-
>remove_handler(signalSet);
restart = RestartTestRunner::mRestart;
if (restart)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) server::main: "
"Resetting event loop before restart.\n"));
ACE_Reactor::instance()-
>reset_reactor_event_loop();
}
delete pRunner;
} while (restart);
ACE_DEBUG ((LM_INFO,
"(%P|%t) server::main: Server stopped.\n"));
return 0;
}
-------------------------------------
----- File: client.cpp -----
#include "tao/ORB.h"
#include "tao/Object.h"
#include "RestartTestC.h"
int main(int argc, char * argv[])
{
try
{
CORBA::ORB_var mOrb = CORBA::ORB_init(argc, argv);
// Resolve to the target object.
CORBA::Object_var mObj = mOrb-
>resolve_initial_references("Test");
RestartTest::RestartTestIntf_var testObj =
RestartTest::RestartTestIntf::_narrow(mObj.in());
CORBA::String_var msg = CORBA::string_dup("Hello World!");
ACE_DEBUG ( (LM_DEBUG,
"(%P|%t) client::main: "
"Calling method test_echo_string....\n"));
CORBA::String_var retVal = testObj->test_echo_string(msg);
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) client::main: "
"Server replied with: %s.\n",
retVal.in()));
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) client::main: "
"Restarting server....\n"));
testObj->test_restart();
}
catch (const CORBA::Exception & e)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) client::main: "
"Caught CORBA Exception while calling server: "));
e._tao_print_exception("\n");
return -1;
}
return 0;
}
-------------------------------------
----- File: restart.mpb -----
project: taoidldefaults {
includes += $(ACE_ROOT) $(ACE_ROOT)/TAO
libpaths += $(ACE_ROOT)/lib
libs += ACE TAO
IDL_Files {
RestartTest.idl
}
}
-------------------------------------
----- File: restart.mpc -----
project(restart_test_client): restart {
exename = client
Source_Files {
client.cpp
RestartTestC.cpp
}
}
project(restart_test_server): restart {
exename = server
libs += TAO_PortableServer TAO_IORTable
Header_Files {
RestartTestIntf_i.h
RestartTestRunner.h
}
Source_Files {
RestartTestIntf_i.cpp
server.cpp
RestartTestS.cpp
RestartTestC.cpp
RestartTestRunner.cpp
}
}
-------------------------------------
----- File: restart.mwc -----
workspace {
restart.mpc
}
SAMPLE FIX/WORKAROUND:
More information about the Ace-users
mailing list