2

I am implementing a profiler. I want to use the Constructor/Destructor idiom to keep track of when I enter/exit a function.

A rough outline of my code is as follows:

class Profile
{
   Profile(void);   //Start timing
  ~Profile(void);   //Stop timer and log
};
//...
Game::Game(void) : m_Quit(false)
{
  Profile p();
  InitalizeModules();
  //...
}

However, when I run it, the Constructor and destructor are not being called. Even when I disassemble, there are no references to Profile::Profile(). I understood that the standard specifies that an instance with a non-trivial constructor cannot be optimized out by the compiler.

There are no optimization flags on the command line of either the compiler or the linker.

I also tried specifying attribute((used)), but to no avail.

Here is the disassembly:

(gdb) disassemble Ztk::Game::Game
Dump of assembler code for function Ztk::Game::Game():
   0x00000000004cd798 <+0>:     push   %rbp
   0x00000000004cd799 <+1>:     mov    %rsp,%rbp
   0x00000000004cd79c <+4>:     push   %r12
   0x00000000004cd79e <+6>:     push   %rbx
   0x00000000004cd79f <+7>:     sub    $0x30,%rsp
   0x00000000004cd7a3 <+11>:    mov    %rdi,-0x38(%rbp)
   0x00000000004cd7a7 <+15>:    mov    -0x38(%rbp),%rax
   0x00000000004cd7ab <+19>:    mov    %rax,%rdi
   0x00000000004cd7ae <+22>:    callq  0x4cdc6a <Ztk::Highlander<Ztk::Game, int>::Highlander()>
   /**   CALL SHOULD BE HERE   **/
   0x00000000004cd7b3 <+27>:    mov    -0x38(%rbp),%rax
   0x00000000004cd7b7 <+31>:    movb   $0x0,(%rax)
   0x00000000004cd7ba <+34>:    callq  0x4e59f0 <Ztk::InitializeModules()>

Indeed there is code generated and linked into the executable

(gdb) disassemble Ztk::Profile::Profile(void)
Dump of assembler code for function Ztk::Profile::Profile():
   0x0000000000536668 <+0>:     push   %rbp
   0x0000000000536669 <+1>:     mov    %rsp,%rbp
   0x000000000053666c <+4>:     sub    $0x20,%rsp
   0x0000000000536670 <+8>:     mov    %rdi,-0x18(%rbp)
   0x0000000000536674 <+12>:    mov    0x8(%rbp),%rax
   0x0000000000536678 <+16>:    mov    %rax,-0x8(%rbp)
   0x000000000053667c <+20>:    mov    -0x8(%rbp),%rax
   0x0000000000536680 <+24>:    mov    %rax,%rsi
   0x0000000000536683 <+27>:    mov    $0x802440,%edi
   0x0000000000536688 <+32>:    callq  0x5363ca <Ztk::Profiler::FindNode(void*)>
Ramon Zarazua B.
  • 7,195
  • 4
  • 22
  • 26
  • If the object is to find bottlenecks, many people want to do it the way you want to (logging routine entry/exit), but there's a better way - stack sampling. [Here's an explanation.](http://stackoverflow.com/questions/4387895/if-profiler-is-not-the-answer-what-other-choices-do-we-have/4390868#4390868) [Zoom](http://www.rotateright.com/) is a highly-respected commercial profiler that does it. The concept may be a mind-bend, but it's actually very simple. – Mike Dunlavey Apr 16 '11 at 17:28

1 Answers1

8
Profile p();

What you've done here is declared a function, called p, that returns an object of type Profile. What you want is this:

Profile p;
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • Gotta love the C++ most vexing parse :) http://arstechnica.com/civis/viewtopic.php?f=20&t=767929 – Drahakar Apr 16 '11 at 15:02
  • Oh!! That must be it! I am used to using this idiom with constructors that toke parameters, I'll try it when I get back to my GCC environment. – Ramon Zarazua B. Apr 16 '11 at 15:58