From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29717 invoked by alias); 15 Feb 2007 18:26:39 -0000 Received: (qmail 29707 invoked by uid 22791); 15 Feb 2007 18:26:38 -0000 X-Spam-Check-By: sourceware.org Received: from upstrm185.psg-ucsf.org (HELO biostat.ucsf.edu) (38.99.193.74) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 15 Feb 2007 18:26:29 +0000 Received: from m201-14.dsl.tsoft.com ([198.144.201.14] helo=wheat.betterworld.us) by biostat.ucsf.edu with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.50) id 1HHlJL-0007M7-I7; Thu, 15 Feb 2007 10:26:27 -0800 Received: from ross by wheat.betterworld.us with local (Exim 4.63) (envelope-from ) id 1HHlJJ-0002Bk-Rz; Thu, 15 Feb 2007 10:26:25 -0800 Date: Thu, 15 Feb 2007 21:24:00 -0000 From: Ross Boylan To: Michael Veksler Cc: Ross Boylan , gdb@sourceware.org Subject: Re: Associating C++ new with constructor Message-ID: <20070215182625.GX5871@wheat.betterworld.us> References: <20070215073516.GW5871@wheat.betterworld.us> <45D46192.30504@tx.technion.ac.il> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <45D46192.30504@tx.technion.ac.il> User-Agent: Mutt/1.5.13 (2006-08-11) X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2007-02/txt/msg00162.txt.bz2 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 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 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