Step 1: change all malloc’s, realloc’s and frees in your software with own versions. E.g: allocate, reallocate, deallocate. Prototypes of such functions can be found in the file common.h
#define array(name,size,type) type* name = allocate(size,type)
#define reallocate(thing, size, type) (type*) bpmdj_realloc(thing,sizeof(type)*(size))
#define deallocate(thing) bpmdj_free(thing);void * bpmdj_alloc(int size, char* file, int line);
void * bpmdj_realloc(void* thing, int size);
void bpmdj_free(void*);
Step 2: modify the library to NOT replace the standard memory operations. The only files needed from the electric fence package are efence.h page.c, efence.c and efence-print.cpp
Step 2.1: modify all references to malloc, calloc, realloc and free in efence.c to efence_malloc, efence_calloc, efence_realloc and efence_free. Make sure that prototypes for these functions are added into efence.h.
void * efence_realloc(void * oldBuffer, size_t newSize)
{
void * newBuffer = efence_malloc(newSize);
…
efence_free(oldBuffer);
…
}void * efence_malloc(size_t size)
{
…
}
void * efence_calloc(size_t nelem, size_t elsize)
{
…
}
Step 2.2: modify the efence_free function to return a boolean. If the freeing was successfull true should be returned. If not because the pointer itself was not within range of the efence allocated memory thenen it should return false. This will later prove to be very usefull to write a generic deallocate function.
{
…
if ( address == 0 )
{
unlock();
return true;
}
…
if ( !slot )
{
unlock();
return false;
}
// removed EF_Abort(“efence_free(%a): address not from efence_malloc().”, address);
…
return true;
}
Step 2.3: the standard efence-print library makes ues of its own printing functions. These can be safely removed because the standard C library functions no longer pose a reentrance thread. Thus, remove printNumber and vprint. Replace all vprint calls with vprintf and include the necessary #include <stdlib.h>
Step 2.4: change efence-print.cpp, efence.cpp, page.cpp, efence.h by putting an #ifdef EFENCE in front and an #endif in the back of the file. This will make it possible to remove the entire EFENCE from compiling.
Step 3: write your own memory functions as declared in step 1. These are straightforward, except for the deallocate function. Here we must differentiate between efence-allocated chunks and an standard-malloced chunks. This can be done as follows.
{
#ifdef EFENCE
if (!efence_free(a))
#endif
free(a);
}void* bpmdj_alloc(int length, char* file, int line)
{
void * result;
assert(length>=0);
#ifdef EFENCE
result = efence_malloc(length);
#else
result = malloc(length);
#endif
if (!result)
printf(“Error: %s(%d): unable to allocate %d bytes \n”,file,line,length);
assert(result);
return result;
}
void* bpmdj_realloc(void* thing, int size)
{
void * result;
assert(size);
#ifdef EFENCE
result = efence_realloc(thing,size);
#else
result = realloc(thing,size);
#endif
assert(result);
return result;
}
This should do the trick. To use it simply put the object files efence.o, page.o, efence-print.o and common.o into your program. When you want checks pass -DEFENCE to the compiler, in the other case simply ommit it. These files can be downloaded here. This should make it possible to debug QT applications easily under linux.