Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Ross Boylan <ross@biostat.ucsf.edu>
To: gdb@sourceware.org
Cc: Ross Boylan <ross@biostat.ucsf.edu>
Subject: Associating C++ new with constructor
Date: Thu, 15 Feb 2007 11:50:00 -0000	[thread overview]
Message-ID: <20070215073516.GW5871@wheat.betterworld.us> (raw)

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<typename T> 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 <main+86>:	movl   $0x2c,0xc(%esp)
0x08048ca4 <main+94>:	movl   $0x804910d,0x8(%esp)
0x08048cac <main+102>:	movl   $0x8049166,0x4(%esp)
0x08048cb4 <main+110>:	movl   $0x4,(%esp)
0x08048cbb <main+117>:	call   0x8048eac <_ZnwjPKcS0_m>
0x08048cc0 <main+122>:	mov    %eax,%ebx
0x08048cc2 <main+124>:	mov    %ebx,(%esp)
0x08048cc5 <main+127>:	call   0x8048e9e <A>
0x08048cca <main+132>:	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 <A> 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


             reply	other threads:[~2007-02-15  7:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-15 11:50 Ross Boylan [this message]
2007-02-15 13:35 ` Daniel Jacobowitz
2007-02-15 15:38 ` Michael Veksler
2007-02-15 21:24   ` Ross Boylan
2007-02-15 22:10     ` Michael Veksler
2007-02-16  5:03       ` Ross Boylan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070215073516.GW5871@wheat.betterworld.us \
    --to=ross@biostat.ucsf.edu \
    --cc=gdb@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox