Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding "new" and Logging data about the caller

I'm trying to write a memory profiler and so far have been able to get my custom functions to work for malloc, free, new and delete. I tried using __FILE__ and __LINE__ to log the originator inside the overloaded new method, but (as expected) it just gives the details of where the overloaded function is. Is there a way to get the details about the originator to the overloaded functions without doing any changes to existing code of the component being tested (like #define for malloc)?

The function I'm using is:

void* operator new (size_t size)
{
    if(b_MemProfStarted)
    {
        b_MemProfStarted = false;
        o_MemLogFile << "NEW: " << "| Caller: "<< __FILE__ << ":"
                << __LINE__ << endl;
        b_MemProfStarted = true;
    }

    void *p=malloc(size);
    if (p==0) // did malloc succeed?
    throw std::bad_alloc(); // ANSI/ISO compliant behavior

    return p;
}

The bool b_MemProfStarted is used to avoid recursive calls on ofstream and map.insert.

like image 393
Gayan Avatar asked Oct 14 '22 13:10

Gayan


1 Answers

You can write

new(foo, bar) MyClass;

In this case the following function is called

void*operator new(std::size_t, Foo, Bar){
    ...
}

You can now call

new(__LINE__, __FILE__) MyClass;

and use the data with

void*operator new(std::size_t, unsigned line, const char*file){
    ...
}

Adding a macro

#define new new(__LINE__, __FILE__)

to the code being monitored will catch most invocations without needing source code changes.

It's not perfect as you could call the operator new directly for example. In that case the preprocessor will turn your code into garbage. I know of no better way though.

like image 197
B.S. Avatar answered Oct 25 '22 17:10

B.S.