Search code examples
debuggingstacktrace32lauterbachautosar

How to measure the amount of memory consumed by the stack?


With Lauterbach TRACE32, how to measure the amount of memory consumed by the stack when the application is running?

I am using AUTOSAR OS on a PowerPC CPU.


Solution

  • In case you'd like to know the memory consumed by the stacks of the tasks I think the easiest way is to consult window TASK.STacK.view. Ensure the following to get TASK.STacK.view working

    • Set-up the debuggers OS awareness (after loading your ELF), with TASK.ORTI for AUTOSAR or TASK.CONFIG for any other target OS.
    • Initialize the stacks of your task with a magic pattern, which can be done in the start code of your OS or with TRACE32 Data.Set command.
    • Possibly declare the magic initialization pattern to the debugger with command TASK.STacK.PATtern, if not detected by the OS awareness.

    In case you'd like to know the memory consumed by the stack of a bare-metal application you have to check this via a PRACTICE script.

    The basic idea here is to initialize the stack with a fixed pattern (before the application starts) and than check later which percentage of the stack does not longer contain the initialization pattern.

    You can do this in the following three steps:

    1st initialize your stack with a magic pattern after loading your ELF like this (or do this in the start-up code of your application):

    GLOBAL &lowAddr &highAddr &magicPattern
    &lowAddr=ADDRESS.OFFSET(__stack_start)   // assign here the upper border of the addressrange occupied by your stack
    &highAddr=ADDRESS.OFFSET(__stack_end)-1  // assign here the lower border of the addressrange occupied by your stack 
    &magicPattern=0xCCCCCCCC   // any 32-bit you like which appears unlikely on the used part of the stack 
    Data.Set &lowAddr--&highAddr %Long &magicPattern   // initialize the stack
    

    Secondly create a script (stackcheck.cmm) to check the stack usage like this:

    PRIVATE &lowAddr &highAddr &pattern &addr
    ENTRY   &lowAddr &highAddr &pattern
    
    IF ("&lowAddr"=="")||("&highAddr"=="")||("&pattern "=="")
    (
        PRINT %ERROR "At least one of the 3 required parameters is missing"
        ENDDO
    )
    VAR.NEWGLOBAL int \stacksize=0
    VAR.NEWGLOBAL int \stackusage=0
    
    &addr=&lowAddr   
    WHILE (Data.LONG(D:&addr)==&pattern)&&(&addr<&highAddr)
        &addr=&addr+4
    
    Var.Set %SPaces \stacksize = (&highAddr - &lowAddr) + 1
    Var.Set %SPaces \stackusage = (&highAddr - &addr) + 1
    Var.View \stacksize \stackusage (100*\stackusage)/\stacksize    // Show result
    ENDDO
    

    (You might want to optimize the way to search through the address-range of the stack.)

    Finally call the script to detect the current stack usage like this:

    DO stackcheck.cmm &lowAddr &highAddr &magicPattern
    

    If you want to check the stack-usage pretty often you might want to use MENU.AddTool to create a button for this in the tool-bar of TRACE32.