Nintendo DS: Guru Meditation error

The processors of the Nintendo DS, an ARM946E-S and ARM7TDMI, support hardware exceptions such as “Data Abort – accessing invalid memory addresses” and “Undefined Instruction”.

The Nintendo DS homebrew library libnds supports exception handling and comes with a default handler that displays the exception type, at which address in the instruction sequence the exception occured and a dump of all registers.

In this article I explain what you can do with this information and why it is useful during development.

libnds exceptionTest example

Copy&Paste from “devkitPro/examples/nds/debugging/exceptionTest/exceptionTest.c”:

When you build and run the example, it displays:libnds_guru_meditation_data

Guru Meditation origin

Guru Meditation is the name of the error that occurred on early versions of the Commodore Amiga computer when they crashed. It is analogous to the “Blue Screen Of Death” in Microsoft Windows operating systems.

The Guru Meditation error message was a black screen with the following animation at the top:

Amiga Guru Meditation Error

Decode NDS Guru Meditation data abort message

One of the Nintendo DS variants of the Guru Meditation error message is the data abort, which includes the following information:

The first line is always “Guru Meditation Error!”, followed by the type of the exception:

The libnds default exception handler displays “Data Abort” and “Undefined Instructions” exceptions.

Below the exception type is “pc” and “addr” displayed:

“pc” is short for Program Counter. The Program Counter register indicates where the processor is in its instruction sequence. In this case, it’s the address of the instruction that caused the exception.

“addr” represents the exception address. In this case, writing to the memory address 0xFA:

This again is followed by a register dump:

  • r0 – r12 are the so called General Purpose Registers.
  • sp (r13) is the Stack Pointer Register, which indicates the current top of stack memory.
  • lr (r14) represents the Link Register, which holds the return address when the current function completes (it’s the address of the caller).
  • pc (r15) is short for Program Counter. The Program Counter register indicates where the processor is in its instruction sequence.

The last information in the error report is a memory dump of the top 80 bytes of stack memory:

  • First column specifies the stack address (0B003CF8)
  • Second column shows the 32bit value from the stack address (0B000000)
  • Third column shows the 32bit value from the stack address + 4 bytes (02000180)

How to make use of all this

This information is informative only when the output file was built with debug information. You can include debug information by adding the -g option (produce debugging information) to CFLAGS in the project makefile:

Copy&Paste from “exceptionTest” makefile:

devkitPro contains an application called “arm-eabi-addr2line.exe”, located in “devkitPro/devkitARM/bin”. It can be used to convert addresses into line number/file name pairs. It supports the following command line options:

We are interested in the address where the Data Abort exception occured, named “pc” here:

I used the following commandline for conversion:

The output is:

When you scroll at the beginning of this article, where I present the source code of the exceptionTest example, you see line 18 is inside main(), which is stored in exceptionTest.c and contains the code that writes to the address 0xFA.

Conclusion

Make sure to install an exception handler in your projects. It’s very helpful to actually see that an error occured rather than a freeze. libnds makes it enormously easy, it’s just one line of code!