Hot!How to view exception call stack > 1 depth?

Author
krbvroc1
New Member
  • Total Posts : 24
  • Reward points : 0
  • Joined: 2016/05/10 16:18:59
  • Location: 0
  • Status: offline
2017/10/01 10:37:20 (permalink)
0

How to view exception call stack > 1 depth?

I might be missing something but my code is hitting an exception under MPLAB X IDE v4.00 with ICD3. The call stack only shows a single level of the exception. Is there some way to see more depth in the call stack? The exception is occurring in a common routine and I'd like to know who is calling it.
#1

5 Replies Related Threads

    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 2645
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: How to view exception call stack > 1 depth? 2017/10/01 13:47:23 (permalink)
    0
    What chip are you using?
    Code?
     
    The stack won't contain the caller function, only the return address, but it would be near enough if you print the func. address then subtract return from func.
    If it was 16bit, you could get [SP-2] and [SP-4]
     
    Is it an address error?, divide by zero?

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #2
    aschen0866
    Super Member
    • Total Posts : 4355
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: How to view exception call stack > 1 depth? 2017/10/01 15:35:20 (permalink)
    +1 (1)
    If this is about PIC32, you can copy general-exception.S from <install>\pic32-libs\libpic32\startup and add it to the project. Set a breakpoint before

    la k0,_general_exception_handler
    nop

    If the breakpoint is hit, the ra register should contain the return address of the calling function. You should be able to look up this address if you generate the assembly listing using xc32-objdump with the -S option.
    #3
    krbvroc1
    New Member
    • Total Posts : 24
    • Reward points : 0
    • Joined: 2016/05/10 16:18:59
    • Location: 0
    • Status: offline
    Re: How to view exception call stack > 1 depth? 2017/10/01 18:10:51 (permalink)
    0
    It is the PIC32MX. I thought the whole point of a debug IDE was to handle this stuff for me?
     
    When the exception occurred it did show the immediate caller, but no more info. Since that was a library call of mine, I needed to know who was calling that function. I guess the IDE does not walk back through the frame pointers to generate a call trace even though the window is called 'call trace'?
     
    Also, one time while debugging using the ICD3 I tried to look at a call trace but it wasn't deep enough and it said something about 'fast stepping' - never figured out what that meant or where that option was to change it.
    #4
    simong123
    Lab Member No. 003
    • Total Posts : 1269
    • Reward points : 0
    • Joined: 2012/02/07 18:21:03
    • Location: Future Gadget Lab (UK Branch)
    • Status: offline
    Re: How to view exception call stack > 1 depth? 2017/10/01 18:48:00 (permalink)
    +2 (2)
    During an exception there is a high likelyhood that the stack has been trashed, and it is not to be trusted. In fact for this reason it is common to allocate a separate stack for exception mode to allow the use of standard library functions like printf, so the debugger would have no way of knowing where the user mode stack is.
     
    For this kind of debugging you can create a couple of global variables and a macro or two to set them to usefull values before calling a function e.g.
     

    uint32_t excep_line;
    char *excep_file;
     
    #ifdef __DEBUG
    #define SET_EXCEP_DATA() do{excep_line=__LINE__;excep_file=__FILE__;}while(0)
    #else
    #define SET_EXCEP_DATA()
    #endif

    then 'call' the macro before all the calls to your library function. You can then examine these variables when an exception occurs.
    #5
    simong123
    Lab Member No. 003
    • Total Posts : 1269
    • Reward points : 0
    • Joined: 2012/02/07 18:21:03
    • Location: Future Gadget Lab (UK Branch)
    • Status: offline
    Re: How to view exception call stack > 1 depth? 2017/10/02 07:21:10 (permalink)
    +1 (1)
    Just to expand a bit on the above, and make it more usefull.
     
    I use the following 2 files in my projects (well, they include more but I've trimmed them for relavence)
     
    debug.c
    #include <xc.h>
    #include <stdint.h>

    #ifdef __DEBUG
    char *excep_file;
    uint32_t excep_line;
    #endif

    debug.h
    #ifndef DEBUG_H
    #define    DEBUG_H

    #ifdef __DEBUG
    extern char *excep_file;
    extern uint32_t excep_line;

    #define _DBFL(fun,...) (excep_file=__FILE__,excep_line=__LINE__,fun(__VA_ARGS__))
    #endif

    #endif    /* DEBUG_H */



    If I am having trouble locating the source of an exception in a function, for example
    uint32_t M24AA02Read(uint32_t addr,uint8_t *dest,uint32_t size);

    I just #include debug.h and add the wrapper in the header file where the function is defined:-
    #ifndef M24AA02_H
    #define    M24AA02_H

    #include "debug.h"

    uint32_t M24AA02Read(uint32_t addr,uint8_t *dest,uint32_t size);
    uint32_t M24AA02Write(uint32_t addr,uint8_t *src,uint32_t size);

    #ifdef __DEBUG
    #define M24AA02Read(...) _DBFL(M24AA02Read,__VA_ARGS__)
    #endif

    #endif    /* M24AA02_H */

    This automatically sets excep_line and excep_file at every function call to M24AA02Read() in debug mode (__DEBUG is a standard macro set by MPLabX), without having to modify any other files. It also preserves the return value so can be used in if() statements etc.
            SETUPDATA_V1 sd;

            if (M24AA02Read(0,(uint8_t*)&sd,sizeof(sd)))
            {
                uint16_t crc=CalcCRC16(&sd.data,sizeof(sd.data));
                
                if (crc==sd.crc)
                {
                    SetupData=sd;
                }
            }

    This expands to
      SETUPDATA_V1 sd;

      if ((excep_file="../main.c",excep_line=558,M24AA02Read(0,(__uint8_t*)&sd,sizeof(sd))))
      {
       __uint16_t crc=CalcCRC16(&sd.data,sizeof(sd.data));

       if (crc==sd.crc)
       {
        SetupData=sd;
       }
      }

    It's also safe for if .. else statements as well
            if (ReadAltSetup)
                M24AA02Read(32,(uint8_t*)&sd,sizeof(sd));
            else
                M24AA02Read(0,(uint8_t*)&sd,sizeof(sd));
    works just fine.
    #6
    Jump to:
    © 2018 APG vNext Commercial Version 4.5