Author Topic: Exception handler  (Read 4864 times)

Offline aaronlawrence

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Exception handler
« on: February 22, 2010, 11:51:40 PM »
Hi all, I have made myself a small loop to jump to, if my code crashes. It basically flashes some LEDs at the moment, and I suppose will do more later. I'm currently using it for Asserts and the like.

I would like to change the default exception handlers so if something else goes wrong, it also jumps to this loop.

I see that currently in jumps to default_code: label in startup_gnu.s. How would I change this? Is there some kind of API, or do I just overwrite the exception handler addresses, or ... ?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3068
    • View Profile
    • uTasker
Re: Exception handler
« Reply #1 on: February 23, 2010, 01:37:37 AM »
Hi Aaron

The vector table has interrupts for:
- undefined instructions
- swi
- pre-fetch abort
- data abort

These are all set to go to an endless loop default_code (in the GCC start-up). The idea is that, when working with a debugger, the debugger can be stopped and the reason for the error found by looking at the information on the present stack: http://www.utasker.com/forum/index.php?topic=535.msg2279#msg2279 (this is generally valid for ARM7s).

The peripheral interrupts are all set to, as default, the routine _Default_IRQ_handler() in LPC23xx.c. This is a dummy routine that doesn't do anything - just returns. If a peripheral should be enabled with interrupts but no handler specifically defined its interrupt would end up here. It is however quite unlikely that this will actually occur - perhaps when writing a new interrupt driven peripheral interface and setting the wrong vector or forgetting to set any vector. This routine can be used to call your other exception error handler by entering a call to it in that routine.

Regards

Mark

Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Prefetch Abort debugging
« Reply #2 on: April 02, 2010, 07:35:34 AM »
I'm using LPC2387 and during the normal operation I got a Prefetch Abort Exception.
To determine the cause I put a breakpoint and had a look to the differents registers.
I saw that at this time r14_abt = 0x02.
If I substract 4 to see the PC address of the exception source I should got the caller address, but in this case it means nothing?
I tried :
Code: [Select]
SUBS PC,R14,#4 (to get back to the exception caller) but it goes nowhere.

How can I see what was the address which caused this exception?
How is it possible to have R14 = 0x02 during an exception ?

Thanks for help.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3068
    • View Profile
    • uTasker
Re: Exception handler
« Reply #3 on: April 06, 2010, 01:25:55 AM »
Hi Hervé

A pre-fetch abort exception is quite rare. It means that the program is trying to execute code from an area of the memory map that doesn't exist. Generally this happens when there is a pointer being used to call code but this pointer is either not initialised or has been corrupted.

I had a go at generating an intentional pre-fetch abort to see exactly what happens.

            void (*test_call)(void);
            test_call = 0x40300000;
            test_call();


Since there is no memory at 0x40300000 the call results in this error. It is possible to directly position a break point at the address 0xc to catch this when it arrives.

I tried this using IAR and Rowley Crossworks to be sure that what I saw was consistent. What I saw was that the processor's current mode was 0x1f before the abort (system) and 0x17 after the abort took place (abort).

The address calling the bad jump was at 0x2378.

The abort R14 showed 0x40300004. This is the next instruction address after the bad access, which was 0x40300000.
The user R14 showed 0x0000237D

This suggests to me that, in the case of a pre-fetch abort, the abort R14 can not be used as indication of the source of the error since the error has already previously occurred (in your case it looks like an access to 0xfffffffd (?)). However the user R14 seems to contain information about where it came from.

Therefore I suggest that you set a break point on the address 0xc and then look at the user R14 value to see whether that matches with the source of the error.

Note however that some crashes take place via a multiple of errors. For example, the bad call pointer may not directly result in a pre-fetch error if it actually points to memory that exists. This may cause some strange code to be executed, which then calls further bad calls which eventually crash. These can be much more difficult to solve and involves also working through the call stack to get an idea of where it started to go wrong...

Good luck!

Regards

Mark