[omniORB] heap corruption in _CORBA_Sequence destructor
Martin Trappel
0xCDCDCDCD at gmx.at
Tue Aug 26 09:15:13 BST 2008
Andrew Buza wrote:
> I posted a thread about problems I was having using CORBA sequences
> back in June ( http://www.omniorb-support.com/pipermail/omniorb-list/2008-June/029546.html
> ). Following Martin's suggestion, I double-checked my allocations, use
> of _var types, etc., but was unable to find anything that (to my eyes)
> was wrong. Coming back to that problem now, I have a sample typical of
> where I'm having difficulty. I have the following (abridged) IDL:
>
> struct Node
> {
> string kind;
> string key;
> };
>
> typedef sequence<Node> NodeList;
>
> interface Hierarchy
> {
> Node getRootNode();
> NodeList getChildren(in Node n);
> };
>
> My client attempts to get a list of all nodes with kind == "Queue" like so:
>
> {
> std::list<std::string> queues;
> //... get Hierarchy object reference...
> Node_var root = hierarchy->getRootNode();
> visit_node(hierarchy, root, queues);
> }
>
> void visit_node(Hierarchy_ptr hierarchy, Node const & node,
> list<string> &queues)
> {
> if(strcmp(node.kind,"Queue") == 0)
> {
> queues.push_back(string(node.key));
> }
>
> NodeList_var children = hierarchy->getChildren(node);
> CORBA::ULong nchildren = children->length();
> for(CORBA::ULong c = 0; c < nchildren; c++)
> {
> Node const & node = children[c];
> visit_node(hierarchy, node, queues);
> }
> }
>
> When this is run I'll get a message indicating heap corruption and the
> IDE (MSVC8.0) will break in the _CORBA_Sequence destructor.
>
> Is the listing above correct, or is there something I'm not
> understanding about memory management in CORBA?
>
Your code looks OK to me.
Indeed, when I set up a very simple example with your IDL I don't have
any problems. (see attached example file)
Have you run your tests in-process or remotely?
br,
Martin
-------------- next part --------------
//
// Example code for implementing IDL interfaces in file node.idl
//
#include "stdafx.h"
#include <iostream>
#include "node.hh"
#include <boost/foreach.hpp>
#include <list>
//
// Example class implementing IDL interface Hierarchy
//
class Hierarchy_i: public POA_Hierarchy {
private:
// Make sure all instances are built on the heap by making the
// destructor non-public
//virtual ~Hierarchy_i();
public:
// standard constructor
Hierarchy_i();
virtual ~Hierarchy_i();
// methods corresponding to defined IDL attributes and operations
Node* getRootNode();
NodeList* getChildren(const Node& n);
};
//
// Example implementational code for IDL interface Hierarchy
//
Hierarchy_i::Hierarchy_i(){
// add extra constructor code here
}
Hierarchy_i::~Hierarchy_i(){
// add extra destructor code here
}
// Methods corresponding to IDL attributes and operations
Node* Hierarchy_i::getRootNode(){
// insert code here and remove the warning
Node_var n = new Node;
n->key = "ROOT";
n->kind = "X";
return n._retn();
}
NodeList* Hierarchy_i::getChildren(const Node& n){
// insert code here and remove the warning
NodeList_var nl = new NodeList;
if(0==strcmp(n.key, "ROOT")) {
nl->length(2);
nl[0].kind = "C";
nl[0].key = "Child 1";
nl[1].kind = "C";
nl[1].key = "Child 2";
}
return nl._retn();
}
// End of example implementational code
using namespace std;
void visit_node(Hierarchy_ptr hierarchy, Node const & node, list<string> &queues)
{
if(strcmp(node.kind,"C") == 0)
{
queues.push_back(string(node.key));
}
NodeList_var children = hierarchy->getChildren(node);
CORBA::ULong nchildren = children->length();
for(CORBA::ULong c = 0; c < nchildren; c++)
{
Node const & node = children[c];
visit_node(hierarchy, node, queues);
}
}
int main(int argc, char** argv)
{
using namespace std;
try {
// Initialise the ORB.
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
// Obtain a reference to the root POA.
CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
// We allocate the objects on the heap. Since these are reference
// counted objects, they will be deleted by the POA when they are no
// longer needed.
Hierarchy_i* myHierarchy_i = new Hierarchy_i();
// Activate the objects. This tells the POA that the objects are
// ready to accept requests.
PortableServer::ObjectId_var myHierarchy_iid = poa->activate_object(myHierarchy_i);
Hierarchy_var h;
// Obtain a reference to each object and output the stringified
// IOR to stdout
{
// IDL interface: Hierarchy
CORBA::Object_var ref = myHierarchy_i->_this();
CORBA::String_var sior(orb->object_to_string(ref));
std::cout << "IDL object Hierarchy IOR = '" << (char*)sior << "'" << std::endl;
h = Hierarchy::_narrow(ref);
}
// Obtain a POAManager, and tell the POA to start accepting
// requests on its objects.
PortableServer::POAManager_var pman = poa->the_POAManager();
pman->activate();
{
std::list<std::string> queues;
Node_var root = h->getRootNode();
cout << root->key << endl;
visit_node(h, root, queues);
queues;
}
// orb->run();
orb->destroy();
}
catch(CORBA::TRANSIENT&) {
cerr << "Caught system exception TRANSIENT -- unable to contact the "
<< "server." << endl;
}
catch(CORBA::SystemException& ex) {
cerr << "Caught a CORBA::" << ex._name() << endl;
}
catch(CORBA::Exception& ex) {
cerr << "Caught CORBA::Exception: " << ex._name() << endl;
}
catch(omniORB::fatalException& fe) {
cerr << "Caught omniORB::fatalException:" << endl;
cerr << " file: " << fe.file() << endl;
cerr << " line: " << fe.line() << endl;
cerr << " mesg: " << fe.errmsg() << endl;
}
return 0;
}
More information about the omniORB-list
mailing list