[omniORB] omniORB memory issue

Benoît Laurent laurentb81 at gmail.com
Sat Mar 15 20:33:09 GMT 2008


Benoît Laurent a écrit :
> Hi all,
> 
> I've downloaded the last omniORB release, and play a little bit with 
> examples. I am definitly not an ORB expert but, i really need an advise 
> on this issue.
> 
> I've add a small memory checker to the eg1.cc code and I am getting a 
> strange crash ? I use gnu libc malloc hook to "overload" malloc, realloc 
> and free defs, to detect memory errors. But I don't understand why in 
> this case memory seems to be corrupted.
> 
> Thanks in advance
> 
> 
> Here is my gdb output :
> 
> GNU gdb 6.7.1
> Copyright (C) 2007 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later 
> <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-pc-linux-gnu"...
> Warning: the current type check setting does not match the language.
> Using host libthread_db library "/lib/libthread_db.so.1".
> (gdb) r
> Starting program: 
> /home/gnurider/omniORB/omniORB-4.1.2/src/examples/echo/eg1
> [Thread debugging using libthread_db enabled]
> [New Thread 0x2b09e1bb6b20 (LWP 32733)]
> 0x2b09e09d1636 : free bad bloc
> 
> Program received signal SIGABRT, Aborted.
> [Switching to Thread 0x2b09e1bb6b20 (LWP 32733)]
> 0x00002b09e18a73c5 in raise () from /lib/libc.so.6
> (gdb) list *0x2b09e09d1636
> 0x2b09e09d1636 is in omni::orbOptions::importFromFile(char const*) 
> (../../../../include/omniORB4/stringtypes.h:141).
> 136      if (s && s != empty_string) delete[] s;
> 137    }
> 138    // As CORBA::string_free().
> 139   
> 140    static inline char* dup(const char* s) {
> 141      char* r = alloc(strlen(s));
> 142      if (r) {
> 143        strcpy(r, s);
> 144        return r;
> 145      }
> 
> 
> 
> code:
> #include <echo.hh>
> #include <malloc.h>
> 
> #ifdef HAVE_STD
> #  include <iostream>
>    using namespace std;
> #else
> #  include <iostream.h>
> #endif
> 
> 
>    static void * (*malloc_ptr)(size_t, const void *)          = NULL;
>    static void * (*realloc_ptr)(void *, size_t, const void*)  = NULL;
>    static void   (*free_ptr)(void*, const void *)           = NULL;
> 
>    static void * my_malloc (size_t size, const void *);
>    static void * my_realloc (void * old, size_t size, const void * caller);
>    static void   my_free (void * pointer, const void * caller);
>    static int    check_ptr (void * pointer);
> 
> #define RESTORE_POINTERS()    __malloc_hook = malloc_ptr; \
>                                 __realloc_hook = realloc_ptr; \
>                                 __free_hook = free_ptr;
> 
> #define SAVE_POINTERS()    malloc_ptr = __malloc_hook; \
>                         realloc_ptr = __realloc_hook; \
>                         free_ptr = __free_hook;
> 
> #define INSTALL_HOOKS()    __malloc_hook = my_malloc; \
>                         __realloc_hook = my_realloc; \
>                         __free_hook = my_free
> 
> 
> 
>    // This is the object implementation.
> 
>    class Echo_i : public POA_Echo
> {
>   public:
>     inline Echo_i() {}
>     virtual ~Echo_i() {}
>     virtual char* echoString(const char* mesg);
> };
> 
> 
> char* Echo_i::echoString(const char* mesg)
> {
>   return CORBA::string_dup(mesg);
> }
> 
> 
> //////////////////////////////////////////////////////////////////////
> 
> // This function acts as a client to the object.
> 
> static void hello(Echo_ptr e)
> {
>   if( CORBA::is_nil(e) ) {
>     cerr << "hello: The object reference is nil!\n" << endl;
>     return;
>   }
> 
>   CORBA::String_var src = (const char*) "Hello!";
>   // String literals are (char*) rather than (const char*) on some
>   // old compilers.  Thus it is essential to cast to (const char*)
>   // here to ensure that the string is copied, so that the
>   // CORBA::String_var does not attempt to 'delete' the string
>   // literal.
> 
>   CORBA::String_var dest = e->echoString(src);
> 
>   cout << "I said, \"" << (char*)src << "\"." << endl
>     << "The Echo object replied, \"" << (char*)dest <<"\"." << endl;
> }
> 
> //////////////////////////////////////////////////////////////////////
> 
> int main(int argc, char** argv)
> {
> 
>   SAVE_POINTERS();
>   INSTALL_HOOKS();
> 
>   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 object on the heap.  Since this is a reference
>     // counted object, it will be deleted by the POA when it is no
>     // longer needed.
>     Echo_i* myecho = new Echo_i();
> 
>     // Activate the object.  This tells the POA that this object is
>     // ready to accept requests.
>     PortableServer::ObjectId_var myechoid = poa->activate_object(myecho);
> 
>     // Obtain a reference to the object.
>     Echo_var myechoref = myecho->_this();
> 
>     // Decrement the reference count of the object implementation, so
>     // that it will be properly cleaned up when the POA has determined
>     // that it is no longer needed.
>     myecho->_remove_ref();
> 
>     // Obtain a POAManager, and tell the POA to start accepting
>     // requests on its objects.
>     PortableServer::POAManager_var pman = poa->the_POAManager();
>     pman->activate();
> 
>     // Do the client-side call.
>     hello(myechoref);
> 
>     // Clean up all the resources.
>     orb->destroy();
>   }
>   catch(CORBA::SystemException& ex) {
>     cerr << "Caught 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;
> }
> 
> 
> 
> #define MAGIC_ID    0x12345678
> 
> static void * my_malloc (size_t size, const void * caller)
> {
>   void * bloc;
> 
>   RESTORE_POINTERS();
> 
>   bloc = malloc(size + 4 * sizeof(size_t));
> 
>   SAVE_POINTERS();
>   INSTALL_HOOKS ();
> 
>   if (bloc == NULL)
>     return NULL;
>   * (size_t *) bloc = size;
>   * (size_t *) ((size_t *)bloc  + sizeof(size_t)) = MAGIC_ID;
>   * (size_t *) ((size_t*)bloc + size + 2 * sizeof(size_t)) = MAGIC_ID;
>   * (size_t *) ((size_t*)bloc + size + 3 * sizeof(size_t)) = MAGIC_ID;
> 
>   return ((size_t *)bloc + 2 * sizeof(size_t));
> }
> 
> static void * my_realloc (void * old, size_t size, const void * caller)
> {
>   void * bloc;
> 
>   if (! check_ptr(old)) {
>     fprintf(stderr, "%p : realloc bad bloc\n", caller);
>     abort();
>   }
> 
>   RESTORE_POINTERS();
> 
>   if (old != NULL)
>     bloc = realloc((size_t*)old - 2 * sizeof(size_t),
>         size + 4 * sizeof(size_t));
>   else
>     bloc = malloc(size + 4 * sizeof(size_t));
> 
>   SAVE_POINTERS();
>   INSTALL_HOOKS();
> 
>   if (bloc == NULL)
>     return bloc;
> 
>   * (size_t *) bloc = size;
>   * (size_t *) ((size_t*)bloc  + sizeof(size_t)) = MAGIC_ID;
>   * (size_t *) ((size_t*)bloc + size + 2 * sizeof(size_t)) = MAGIC_ID;
>   * (size_t *) ((size_t*)bloc + size + 3 * sizeof(size_t)) = MAGIC_ID;
> 
>   return ((size_t*)bloc + 2 * sizeof(size_t));
> }
> 
> static void my_free (void * pointer, const void * caller)
> {
>   size_t size;
>   size_t i;
> 
>   if (! check_ptr(pointer)) {
>     fprintf(stderr, "%p : free bad bloc\n", caller);
>     abort();
>   }
> 
>   if (pointer == NULL)
>     return;
> 
>   RESTORE_POINTERS();
> 
>   size = (* (size_t *) ((size_t*)pointer - 2 * sizeof(size_t)));
>   for (i = 0; i < size + 4 * sizeof(size_t); i++)
>     * (char *) ((size_t*)pointer - 2 * sizeof(size_t) + i) = 0x55;
> 
>   free ((size_t*)pointer - 2 * sizeof(size_t));
> 
>   SAVE_POINTERS();
>   INSTALL_HOOKS();
> }
> 
> 
>   static int
> check_ptr (void * pointer)
> {
>   size_t    size;
> 
>   if (pointer == NULL)
>     return 1;
>   if (* (size_t *) ((size_t*)pointer - sizeof(size_t)) != MAGIC_ID)
>     return 0;
>   size = * (size_t *) ((size_t*)pointer - 2 * sizeof(size_t));
>   if (* (size_t *) ((size_t*)pointer + size) != MAGIC_ID)
>     return 0;
>   if (* (size_t *) ((size_t*)pointer + size + sizeof(size_t)) != MAGIC_ID)
>     return 0;
>   return 1;
> }
> 
> _______________________________________________
> omniORB-list mailing list
> omniORB-list at omniorb-support.com
> http://www.omniorb-support.com/mailman/listinfo/omniorb-list
> 


After some investigation, I've fixed my problem, (Pointer arithmetic is 
not that simple).



More information about the omniORB-list mailing list