How do get a stack dump in a custom error handler?

I’m getting an ERR_UNEXPECTEDRST38 once in a while. I suspect it is from a stack corruption that happens while processing timer interrupts. I want to try and trace the issue back to the code that caused the problem.

Is there a routine already written that will format the contents of the stack to a string that I can message out of my embedded device?

I don’t think there is anything in the Rabbit Libs for this and unfortunately by the time you have hit ERR_UNEXPECTEDRST38s things are usually so far off the rails that you can’t rely on getting enough of the system working to do anything useful!

On my product I’ve added a facility to get a dump of the memory out over the network (using the BACnet stack and the Private Data Transfer functionality). This can provide useful information after a crash as you can get some idea of what sort of data has been written over memory areas.


This seems to work:

root void RuntimeErrHandler (int error_code, int more_info,
                                int xpc_val, int address) {
  int i;
  int *stack;
  char buffer[60];                // formatted dump of the stack prior to the exception
  char item[6];
  int mystack = sizeof(i) * 4;    // skip the four values passed into routine

  buffer[0] = 0;                       // clear the output buffer
  stack = &i;
  stack += mystack;               // now pointing to the return address
  for (i = 0; i < 10; i++) {
    sprintf(item, " %04X", *stack++);
    strcat(buffer, item);
  blurtMsg ("Error %d:%d @ %3x:%04x, Stack: %s", error_code, more_info, xpc_val, address, buffer);


See include\errno.h for the list of error_codes.
Address will be the address of the exception handler (See \RabbitX000\BIOSLib\Util.Lib)
The return address on the top of the stack will be pointing back to your line of code that threw the exception. The rest of the stack will be the local variables in the routine, the return address of who called your routine, and then the parameters that were passed to the routine.

blurtMsg() is my routine to send the formatted string over the network to my control software.

You’ve been luckier than me when this has happened! Perhaps its the fact that I use uCOS that makes it more likely that things are unstable at that point?