Benoît Laurent
2008-03-14 03:21:06 UTC
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;
}
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;
}