Decoding runtime error xpc:addr to map file address

I am experiencing a runtime error in my software, based on an RCM3309 and DC9.62. The xpc and address parameters supplied to my runtime error handler don’t seem to match up with any function address in the map file for my software build.

I attempted to verify that this wasn’t down to some stack corruption (code jumping off to unknown territory), by inserting a forced crash (write a value to the location pointed at by a NULL pointer) and then matching the resulting xpc and address parameters to my map file. I was also unable to match these to the function/location where I had inserted the source code to cause the crash (very early in main()).

Can anyone point me at/provide me with any documentation/information on how I translate the runtime error xpc:addr information to locate the faulting function in my map file?

Thanks in advance.

Often the user error handler will catch an uninitialized interrupt. For instance, divide-by-zero generates an interrupt and sends execution to the divide-by-zero vector. If you haven’t defined an error handler for that, then it vectors to the default error handler. So, your XPC:Addr will be pointing to the catch-all error routine. That’s probably why it isn’t pointing to your code.

I wrote a routine to try and snapshot the bottom of the stack and send it to me. You can find that code here. Then you have to trace back the return addresses that are between the arguments that have been pushed onto the stack.

Thanks Ron. That makes sense. I tried your function, but I’m afraid it hasn’t furthered my understanding of the issue.
When you say “you have to trace back the return addresses that are between the arguments that have been pushed onto the stack”, I’m not clear on how I would differentiate between arguments and return addresses, since I don’t know which function calls and associated arguments were involved in the lead up to the runtime error handler being invoked.
Can you clarify any further?

If you look at an assembly listing, you will see how a C routine is called. The compiler pushes the values or addresses of your parameters onto the stack, last to first, then it calls the routine. A call pushes the instruction pointer onto the stack. The called routine uses SP relative addressing to refer to the passed parameters. When the called routine returns, it just pops the return address off the stack back into the instruction pointer. Then, the calling routine strips all the parameters off the stack. If it was a function call, then the return value is one of the items, and it is copied to the variable that has been specified to receive the value.
So, you don’t have any markers in the stack to identify what the stuff is. You have to use the XPC and instruction address, or the return address that is on the top of the stack, to determine what was called and how much stack it used for the call. Then, you can find the next return address and trace back further, if you want.