obtaining callstack level

Discussion in 'C++' started by seannakasone@yahoo.com, Apr 25, 2006.

  1. Guest

    Is there a way to get the callstack level in c++? for example, take
    the following code:

    void call3() {
    //callstack level would be 3
    }

    void call2() {
    //callstack level would be 2
    call3();
    }

    int main() {
    //callstack level would be 1
    call2();
    return 0;
    }

    And I don't mean obtaining it from using a debugger and looking at the
    callstack. I'm mean obtaining it programmatically.
     
    , Apr 25, 2006
    #1
    1. Advertising

  2. Ian Collins Guest

    wrote:
    >
    > And I don't mean obtaining it from using a debugger and looking at the
    > callstack. I'm mean obtaining it programmatically.
    >

    No, not in standard C++.

    --
    Ian Collins.
     
    Ian Collins, Apr 25, 2006
    #2
    1. Advertising

  3. * :
    > Is there a way to get the callstack level in c++? for example, take
    > the following code:
    >
    > void call3() {
    > //callstack level would be 3
    > }
    >
    > void call2() {
    > //callstack level would be 2
    > call3();
    > }
    >
    > int main() {
    > //callstack level would be 1
    > call2();
    > return 0;
    > }
    >
    > And I don't mean obtaining it from using a debugger and looking at the
    > callstack. I'm mean obtaining it programmatically.


    Instrument the functions, that is, add code that maintains a call stack
    level count.

    That can easily be done via the construction and destruction of a local
    object in each function.

    For example, off the cuff,

    class CallTracer
    {
    private:
    static std::size_t& theLevel()
    {
    static std::size_t theLevelVariable = 0;
    return theLevelVariable;
    }

    public:
    CallTracer(){ ++theLevel(); }
    ~CallTracer(){ --theLevel(); }
    static std::size_t level() { return theLevel(); }
    };

    which you'd use like

    void foo3()
    {
    CallTracer tracer;
    std::cout
    << "foo3, at call level " << CallTracer::level()
    << std::endl;
    }

    This counts the calls of functions instrumented this way; if that's not
    enough, use a decent debugger.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Apr 25, 2006
    #3
  4. wrote:
    > Is there a way to get the callstack level in c++? for example, take
    > the following code:


    [...]

    > And I don't mean obtaining it from using a debugger and looking at the
    > callstack. I'm mean obtaining it programmatically.


    If you're not interested in a precise number, but can accept a measure
    that would indicate the stack depth in bytes you can obtain the address
    of one of the function's plain local variables through the & operator
    and cast it to a char * pointer. I've used this technique to track the
    use of stack space during the runtime of a program; see the snapshots at
    <http://www.spinellis.gr/codequality/stack.gif?clcpp>. This technique
    is not portable, but will work on most computer architectures.
     
    Diomidis Spinellis, Apr 25, 2006
    #4
  5. Guest

    Diomidis Spinellis wrote:
    > wrote:
    > > Is there a way to get the callstack level in c++? for example, take
    > > the following code:


    > If you're not interested in a precise number, but can accept a measure
    > that would indicate the stack depth in bytes you can obtain the address
    > of one of the function's plain local variables through the & operator
    > and cast it to a char * pointer. I've used this technique to track the
    > use of stack space during the runtime of a program; see the snapshots at
    > <http://www.spinellis.gr/codequality/stack.gif?clcpp>. This technique
    > is not portable, but will work on most computer architectures.


    The Itanium of course being one of those where it doesn't work; it has
    two
    stacks. C++ doesn't care; you can still implement Standard C++ on it.
    Yet such features explain why Standard C++ doesn't have "a" callstack
    level; it doesn't really make sense.

    HTH,
    Michiel Salters
     
    , Apr 25, 2006
    #5
  6. * :
    > Diomidis Spinellis wrote:
    >> wrote:
    >>> Is there a way to get the callstack level in c++? for example, take
    >>> the following code:

    >
    >> If you're not interested in a precise number, but can accept a measure
    >> that would indicate the stack depth in bytes you can obtain the address
    >> of one of the function's plain local variables through the & operator
    >> and cast it to a char * pointer. I've used this technique to track the
    >> use of stack space during the runtime of a program; see the snapshots at
    >> <http://www.spinellis.gr/codequality/stack.gif?clcpp>. This technique
    >> is not portable, but will work on most computer architectures.

    >
    > The Itanium of course being one of those where it doesn't work; it has
    > two
    > stacks. C++ doesn't care; you can still implement Standard C++ on it.
    > Yet such features explain why Standard C++ doesn't have "a" callstack
    > level; it doesn't really make sense.


    Although a bit off-topic, would you care to elaborate? It's a long time
    since I did any assembly level programming, but the only case of /two/
    stacks I'm familiar with is the normal call stack versus system
    exception handling stack (as on e.g. MC68K). I can't see how ordinary
    function execution could utilize two different stacks, except if the
    Itanium has one stack for return addresses and another for arguments?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Apr 25, 2006
    #6
  7. Ian Collins Guest

    wrote:
    > Diomidis Spinellis wrote:
    >
    >> wrote:
    >>
    >>>Is there a way to get the callstack level in c++? for example, take
    >>>the following code:

    >
    >
    >>If you're not interested in a precise number, but can accept a measure
    >>that would indicate the stack depth in bytes you can obtain the address
    >>of one of the function's plain local variables through the & operator
    >>and cast it to a char * pointer. I've used this technique to track the
    >>use of stack space during the runtime of a program; see the snapshots at
    >><http://www.spinellis.gr/codequality/stack.gif?clcpp>. This technique
    >>is not portable, but will work on most computer architectures.

    >
    >
    > The Itanium of course being one of those where it doesn't work; it has
    > two
    > stacks. C++ doesn't care; you can still implement Standard C++ on it.
    > Yet such features explain why Standard C++ doesn't have "a" callstack
    > level; it doesn't really make sense.
    >

    That's assuming the Itanium user is subscribed to this group :)

    --
    Ian Collins.
     
    Ian Collins, Apr 25, 2006
    #7
  8. Alf P. Steinbach wrote:
    > * :
    >> Diomidis Spinellis wrote:
    >>> wrote:
    >>>> Is there a way to get the callstack level in c++? for example, take
    >>>> the following code:

    >>
    >>> If you're not interested in a precise number, but can accept a measure
    >>> that would indicate the stack depth in bytes you can obtain the address
    >>> of one of the function's plain local variables through the & operator
    >>> and cast it to a char * pointer. I've used this technique to track the
    >>> use of stack space during the runtime of a program; see the snapshots at
    >>> <http://www.spinellis.gr/codequality/stack.gif?clcpp>. This technique
    >>> is not portable, but will work on most computer architectures.

    >>
    >> The Itanium of course being one of those where it doesn't work; it has
    >> two
    >> stacks. C++ doesn't care; you can still implement Standard C++ on it.
    >> Yet such features explain why Standard C++ doesn't have "a" callstack
    >> level; it doesn't really make sense.

    >
    > Although a bit off-topic, would you care to elaborate? It's a long time


    My understanding is that the Itanium has SPARC-like register windows
    backed by a hardware assisted so-called register stack engine (RSE).
    When a function calls another arguments are placed into the general
    purpose registers Gr32-Gr128. Through an alloc instruction the called
    function specifies the layout of its stack frame (input registers, local
    registers, and output registers). This has the effect of mapping the
    calling function's output registers to the called function's input
    registers, and thus passing the function arguments through the registers
    without any overhead. The registers get renamed at the point of the
    call, so that all functions will always see their registers starting at
    Gr32. When the 96 general purpose registers used for implementing the
    scheme run out, a spill will burst-write registers to the special
    register stack; later when the stack is unwound a fill will read the
    contents back from memory.

    Why are two stacks needed? My guess is that it was simpler to optimize
    the RSE hardware (for example caching or the burst mode alignment
    requirements) if the return addresses and the normal stack push/pop
    instructions didn't interfere with the register spill stack.

    You can find a few more details in this article:
    http://www.intel.com/cd/ids/developer/asmo-na/eng/20314.htm?page=1

    --
    Diomidis Spinellis
    Code Quality: The Open Source Perspective (Addison-Wesley 2006)
    http://www.spinellis.gr/codequality?clcpp
     
    Diomidis Spinellis, Apr 25, 2006
    #8
  9. Ian Collins Guest

    Diomidis Spinellis wrote:
    > wrote:
    >
    >> Is there a way to get the callstack level in c++? for example, take
    >> the following code:

    >
    >
    > [...]
    >
    >> And I don't mean obtaining it from using a debugger and looking at the
    >> callstack. I'm mean obtaining it programmatically.

    >
    >
    > If you're not interested in a precise number, but can accept a measure
    > that would indicate the stack depth in bytes you can obtain the address
    > of one of the function's plain local variables through the & operator
    > and cast it to a char * pointer. I've used this technique to track the
    > use of stack space during the runtime of a program; see the snapshots at
    > <http://www.spinellis.gr/codequality/stack.gif?clcpp>. This technique
    > is not portable, but will work on most computer architectures.


    Do you get artificially high values?

    I was thinking of the case where the compiler could use registers for
    local variables. Until you start taking their address which would
    defeat that optimisation.

    --
    Ian Collins.
     
    Ian Collins, Apr 25, 2006
    #9
  10. * Diomidis Spinellis:
    >
    > You can find a few more details in this article:
    > http://www.intel.com/cd/ids/developer/asmo-na/eng/20314.htm?page=1


    Thanks. It's, well, perplexing. They have cached the stack, but turned
    the conceptual picture 180 degrees around so that it seems main memory
    is used to relieve what actually is the cache, and instead of making
    this transparent they require direct support from the machine code, and
    therefore (one must presume) limited the mechanism to 64-bit code.

    Hm.

    Hopefully it won't influence ordinary C++ programming, but I saw nothing
    in that article that discussed how the architecture meshed with common
    C++ techniques such as using a pointer or reference to a local variable.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Apr 26, 2006
    #10
  11. Ian Collins wrote:
    > Diomidis Spinellis wrote:
    >> wrote:
    >>
    >>> Is there a way to get the callstack level in c++? for example, take
    >>> the following code:

    >>
    >> [...]
    >>
    >>> And I don't mean obtaining it from using a debugger and looking at the
    >>> callstack. I'm mean obtaining it programmatically.

    >>
    >> If you're not interested in a precise number, but can accept a measure
    >> that would indicate the stack depth in bytes you can obtain the address
    >> of one of the function's plain local variables through the & operator
    >> and cast it to a char * pointer. I've used this technique to track the
    >> use of stack space during the runtime of a program; see the snapshots at
    >> <http://www.spinellis.gr/codequality/stack.gif?clcpp>. This technique
    >> is not portable, but will work on most computer architectures.

    >
    > Do you get artificially high values?
    >
    > I was thinking of the case where the compiler could use registers for
    > local variables. Until you start taking their address which would
    > defeat that optimisation.


    I assume by "high values" you mean high memory addresses, i.e. low stack
    usage values. At most the measure will be off by the number of the
    processor's registers, because even when the compiler allocates local
    variables to registers these have to be stored on the stack when another
    function gets called. In the particular case I wanted to profile the
    stack's growth across millions of function invocations; an offset of a
    few tens of bytes would hardly matter. Function inlining is also
    affecting the results (I used a modified call graph profiler function
    prologue to write the values to a file, so inlined functions weren't
    tracked at all.)

    --
    Diomidis
     
    Diomidis Spinellis, Apr 26, 2006
    #11
  12. Ian Collins Guest

    Diomidis Spinellis wrote:
    > Ian Collins wrote:
    >
    >> Diomidis Spinellis wrote:
    >>
    >>> wrote:
    >>>
    >>>> Is there a way to get the callstack level in c++? for example, take
    >>>> the following code:
    >>>
    >>>
    >>> [...]
    >>>
    >>>> And I don't mean obtaining it from using a debugger and looking at the
    >>>> callstack. I'm mean obtaining it programmatically.
    >>>
    >>>
    >>> If you're not interested in a precise number, but can accept a measure
    >>> that would indicate the stack depth in bytes you can obtain the address
    >>> of one of the function's plain local variables through the & operator
    >>> and cast it to a char * pointer. I've used this technique to track the
    >>> use of stack space during the runtime of a program; see the snapshots at
    >>> <http://www.spinellis.gr/codequality/stack.gif?clcpp>. This technique
    >>> is not portable, but will work on most computer architectures.

    >>
    >>
    >> Do you get artificially high values?
    >>
    >> I was thinking of the case where the compiler could use registers for
    >> local variables. Until you start taking their address which would
    >> defeat that optimisation.

    >
    >
    > I assume by "high values" you mean high memory addresses, i.e. low stack
    > usage values. At most the measure will be off by the number of the
    > processor's registers, because even when the compiler allocates local
    > variables to registers these have to be stored on the stack when another
    > function gets called. In the particular case I wanted to profile the
    > stack's growth across millions of function invocations; an offset of a
    > few tens of bytes would hardly matter. Function inlining is also
    > affecting the results (I used a modified call graph profiler function
    > prologue to write the values to a file, so inlined functions weren't
    > tracked at all.)
    >

    That's a good point, I forgot about calling other functions.

    The only place this would be a problem would be on a Sparc like
    processor that uses register wheels to pass parameters.

    I've used similar techniques to this, along with high water marks.

    --
    Ian Collins.
     
    Ian Collins, Apr 26, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Morten Simonsen

    Retrieve callstack from a Thread

    Morten Simonsen, Sep 17, 2003, in forum: Java
    Replies:
    1
    Views:
    318
    Robert Olofsson
    Sep 17, 2003
  2. Jacob

    Callstack question

    Jacob, Sep 22, 2003, in forum: Java
    Replies:
    0
    Views:
    347
    Jacob
    Sep 22, 2003
  3. pabbu
    Replies:
    8
    Views:
    728
    Marc Boyer
    Nov 7, 2005
  4. callstack level

    , Jul 5, 2006, in forum: Ruby
    Replies:
    3
    Views:
    111
    Robert Klemme
    Jul 6, 2006
  5. Replies:
    1
    Views:
    192
Loading...

Share This Page