Re: Associating C++ new with constructor

Ross Boylan
2007-02-15T18:26:39Z

Daniel, thanks for your response. I've been trying to avoid messing
with the source code, but it sounds as if I'm stuck with it.

I suppose one other option would be go to the source line of the call
to new and try to pull the class out of it. It might work well enough
to do the job.

I was thinking of tools to rewrite the source automatically, and
Michael provides one suggestion below. I have a few questions about
what he wrote.

Before I get to that, though, can anyone explain why gdb was able to
give me the name of the new() function given the address, but couldn't
give me the address when given the name of the function (details in
the original post)?

On Thu, Feb 15, 2007 at 03:35:14PM +0200, Michael Veksler wrote:
> Ross Boylan wrote:
> >This is NOT about the problems setting a breakpoint on a C++
> >constructor!
> >
> >I've been looking for a way to count creations and destructions of C++
> >objects, with the counts kept on a per class basis.
> Many (9?) years ago I have written a dumb perl script to do this task.
> It is
> still being used from time to time, despite valgrind's massif.
> I can't give you the script, without considerable paperwork, since
> it is (C) IBM (and I won't try because it is too embarrassing to
> release such a trivial script).
No problem.
>
> The idea is simple, and took me less than a day to implement:
> Define a template class that can monitor object creation and
> destruction.
> Insert a member of this type into all non-POD classes:
> class MyFoo {
> ....
> ....
> ...
> Count<MyFoo> m_count_for_MyFoo;
> };
>
> This member will be constructed every time your MyFoo is
> constructed. Inside the Count class you can do whatever
> you want, every Count<T> class may update a global
> registry, from which you can print statistics for all Count
> classes.

One nice thing about this vs. the memory corruption detection tools is
that it catches all instance creation, not just stuff on the heap.

>
> Note that the perl script simply detects "class ....." and
> inserts the members into it. The nice thing about this
> template thing, is that it should work well even
> if your MyFoo is also templated, and it works
> well for all possible constructors.
>
> It is imperfect since it can't reliably detect all
> non-POD classes, and it does not work for std::***
> classes. To make it 100% reliable, I had to write
> a complete C++ parser!.

Why isn't this reliable for all classes in your source code (at least
if you add a search for "struct")? Are you referring to cases that
use pre-processor magic, or is there something else?

Another approach is in libcwd, which records the class along with the
memory allocation if you insert a call to AllocTag() after the call to
new. AllocTag uses templates under the hood to get the type of the
pointer automatically, and libcwd provides a macro NEW that will take
care of it automatically, e.g., A *pA = NEW(A()).

This problem was driving me crazy enough that I was looking into
putting hooks in gcc, which has the advantage of providing a C++
parser. That approach has a few disadvantages. Aside from being a
big project (at least for someone like myself who knows little about
compilers), it would be impractical to redistribute.

There seems to be some possibility that the upcoming revision of the
C++ standard will incorporate improved reflection capabilities; that
might help with this problem.

Ross