From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29565 invoked by alias); 15 Feb 2007 07:35:24 -0000 Received: (qmail 29556 invoked by uid 22791); 15 Feb 2007 07:35:24 -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 07:35:19 +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 1HHb9B-0006OP-Lt; Wed, 14 Feb 2007 23:35:17 -0800 Received: from ross by wheat.betterworld.us with local (Exim 4.63) (envelope-from ) id 1HHb9A-0000GG-BW; Wed, 14 Feb 2007 23:35:16 -0800 Date: Thu, 15 Feb 2007 11:50:00 -0000 From: Ross Boylan To: gdb@sourceware.org Cc: Ross Boylan Subject: Associating C++ new with constructor Message-ID: <20070215073516.GW5871@wheat.betterworld.us> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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/msg00154.txt.bz2 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. I've looked at various tools to track memory use, but none of them appear to provide this directly (even when attention is limited to the free store). Some capture the call stack when the call to new is made, but this doesn't definitively identify the class in question. (It can provide the line of the call, but that's an imperfect indicator. If there are multiple calls on one line, or the call is split over several lines, things are ugly. And if we have template class Foo { ..... T* p = new T(); // maybe needs to be new typename T()? ..... }; the source is insufficient to identify the type.) The problem is that the call to new precedes the call to the constructor; new doesn't know the type, and the type is not on the call stack. Might it be possible, programmatically, to trace the stack up, locate the call that will be made next, and get the constructor that way? Here's a toy example on linux-i386: Source line is A *pA = new A(); disassembly 0x08048c9c : movl $0x2c,0xc(%esp) 0x08048ca4 : movl $0x804910d,0x8(%esp) 0x08048cac : movl $0x8049166,0x4(%esp) 0x08048cb4 : movl $0x4,(%esp) 0x08048cbb : call 0x8048eac <_ZnwjPKcS0_m> 0x08048cc0 : mov %eax,%ebx 0x08048cc2 : mov %ebx,(%esp) 0x08048cc5 : call 0x8048e9e 0x08048cca : mov %ebx,0xfffffff4(%ebp) The call stack has main+122 on it. Adding 5 gets me to the next call, and (gdb) info symbol 0x8048e9e A::A() in section .text (which I suppose is what the annotation in the disassembly was about). So my recipe is a) get the address of the caller b) add 5 c) extract the location being called there d) get the symbol being called, and use it to identify the class (this last step involves several substeps, including notably doing the disassemly, getting the symbol, unmangling the symbol, and extracting the class name). Does that have any chance of working with any generality? I'm not necessarily looking to do the instrumentation from within gdb, though I'd certainly like to avoid having to redo the logic of getting debug info, etc.. The most obvious concern is that calls to the c'tor might get optimized away (for example, class A above is empty, but I compiled with g++ -O0). It would also be nice to get the address of new automatically. Can anyone explain why this symbolic lookup failed? (the program wasn't running) (gdb) info symb 0x8048eac # works operator new(unsigned int, char const*, char const*, unsigned long) in section .text (gdb) info add 'operator new(unsigned int, char const*, char const*, unsigned long)' # fails No symbol "'operator new(unsigned int, char const*, char const*, unsigned long)'" in current context. I tried several variants of the name for new; none worked. Incidentally, it would be nice to be able to get all c'tor calls, not just those associated with the heap, but that obviously does run into the problems putting breakpoints on them. It would also require identifying all the c'tors. Thanks. Ross Boylan