[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