title: Capturing function exit time with __gnu_mcount_nc
body: <p>I'm trying to do some performance profiling on a poorly supported prototype embedded platform. </p>
  
  <p>I note that GCC's -pg flag causes thunks to <code>__gnu_mcount_nc</code> to be inserted on entry to every function. No implementation of <code>__gnu_mcount_nc</code> is available (and the vendor is not interested in assisting), however as it is trivial to write one that simply records the stack frame and current cycle count, I have done so; this works fine and is yielding useful results in terms of caller/callee graphs and most frequently called functions.</p>
  
  <p>I would really like to obtain information about the time spent in function bodies as well, however I am having difficulty understanding how to approach this with only the entry, but not the exit, to each function getting hooked: you can tell exactly when each function is entered, but without hooking the exit points you cannot know how much of the time until you receive the next piece of information to attribute to callee and how much to the callers. </p>
  
  <p>Nevertheless, the GNU profiling tools are in fact demonstrably able to gather runtime information for functions on many platforms, so presumably the developers have some scheme in mind for achieving this.</p>
  
  <p>I have seen some existing implementations that do things like maintain a shadow callstack and twiddle the return address on entry to __gnu_mcount_nc so that __gnu_mcount_nc will get invoked again when the callee returns; it can then match the caller/callee/sp triplet against the top of the shadow callstack and so distinguish this case from the call on entry, record the exit time and correctly return to the caller. </p>
  
  <p>This approach leaves much to be desired:</p>
  
  <ul>
  <li>it seems like it may be brittle in the presence of recursion and libraries compiled without the -pg flag</li>
  <li>it seems like it would be difficult to implement with low overhead or at all in embedded multithreaded/multicore environments where toolchain TLS support is absent and current thread ID may be expensive/complex to obtain</li>
  </ul>
  
  <p>Is there some obvious better way to implement a __gnu_mcount_nc so that a -pg build is able to capture function exit as well as entry time that I am missing?</p>