[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