Alerts, Gurus, and Exception Handling¶
When the AmigaOS encounters a fatal error, it displays a Guru Meditation — a black screen with a flashing red box containing two long-word numbers. This article documents the three types of Gurus (processor exceptions, general alerts, specific alerts), the Alert() function, alert number constants, and how to install custom trap handlers. Source: Ralph Babel's The Amiga Guru Book (1993, Ch. 11).
The Alert() function¶
void Alert(ULONG alertNum);
Alert() is an exec.library function that creates a Guru. The parameter (D7) defines the first Guru number. Bit 31 selects the type:
| Bit 31 | Constant | Behavior |
|---|---|---|
| Set | AT_DeadEnd (0x80000000) |
System halts; requires reboot |
| Clear | AT_Recovery |
Recoverable; user can continue |
As of Kickstart 2.0, the second Guru number displayed is always the current task's address (previously, it could be a task address, a special error code, or undefined — never a code address). As of Kickstart 2.0, all Gurus dump registers D0-D7 and A0-A7 to memory starting at location $00000180, useful for ROM-Wack debugging.
The three types of Gurus¶
1. Unexpected processor exceptions (traps)¶
These usually produce a dead-end alert. However, if the exception is synchronous (caused by a specific task operation, e.g. division by zero or an odd-address word access), it can be intercepted via the task's trap handler (tc_TrapCode). If no trap handler is installed, the task is typically aborted.
Only exceptions in user mode are routed through a task's trap vector. Unexpected exceptions in supervisor mode inevitably end up in Alert() — Guru.
Prior to Kickstart 2.0, exceptions 16-24 would always produce Guru $8100000A (AN_BogusExcpt).
2. General alerts¶
General alerts use the AG_* constants in the subsystem-ID field. The alert number encodes a cause and optionally an object:
| Constant | Value | Meaning |
|---|---|---|
AG_NoMemory |
$00010000 |
Insufficient free store |
AG_MakeLib |
$00020000 |
Error during library initialization |
AG_OpenLib |
$00030000 |
OpenLibrary() failed |
AG_OpenDev |
$00040000 |
OpenDevice() failed |
AG_OpenRes |
$00050000 |
OpenResource() failed |
AG_IOError |
$00060000 |
I/O error |
AG_NoSignal |
$00070000 |
AllocSignal() failed |
AG_BadParm |
$00080000 |
Illegal parameter(s) |
AG_CloseLib |
$00090000 |
Mismatched or too many closes |
AG_CloseDev |
$000A0000 |
Ditto (device) |
AG_ProcCreate |
$000B0000 |
CreateProc() etc. failed |
3. Specific (subsystem) alerts¶
These use subsystem-specific AN_* constants. The subsystem ID occupies bits 30-24; bit 15 distinguishes general from specific alerts. The AO_* constants identify the object (which library/device):
Alert objects (AO_*):
| Constant | Value | Subsystem |
|---|---|---|
AO_ExecLib |
$00008001 |
exec.library |
AO_GraphicsLib |
$00008002 |
graphics.library |
AO_LayersLib |
$00008003 |
layers.library |
AO_Intuition |
$00008004 |
intuition.library |
AO_DOSLib |
$00008008 |
dos.library |
AO_ExpansionLib |
$0000800A |
expansion.library |
AO_UtilityLib |
$0000800E |
utility.library |
Exec-specific alerts (AN_*, subsystem $01000000):
| Constant | Value | Meaning |
|---|---|---|
AN_ExcptVect |
$81000001 |
Bad checksum for 68000 exception vectors |
AN_BaseChkSum |
$81000002 |
Bad checksum for ExecBase |
AN_LibChkSum |
$81000003 |
Bad checksum for library jump table |
AN_LibMem |
$01000003 |
No memory to make exec.library |
AN_MemCorrupt |
$81000005 |
Corrupted memory list during FreeMem() |
AN_IntrMem |
$81000006 |
No memory for interrupt servers |
AN_InitAPtr |
$81000007 |
InitStruct() with APTR type |
AN_SemCorrupt |
$81000008 |
Illegal semaphore state during ReleaseSemaphore() |
AN_BogusExcpt |
$8100000A |
Undefined 68000 exception taken |
AN_IOUsedTwice |
$0100000B |
Pending I/O request reused |
AN_MemoryInsane |
$0100000C |
Integrity check on memory list failed |
AN_FreeTwice |
$0100000D |
During AvailMem(MEMF_LARGEST) |
AN_IOAfterClose |
$0100000E |
Closed I/O request reused |
AN_StackProbe |
$0100000F |
Stack overflow (TF_STACKCHK) |
AN_BadFreeAddr |
$01000010 |
No MemHeader for FreeMem() address |
Reading a Guru number¶
A Guru number is a 32-bit value:
31 30-24 23-16 15 14-0
AT subsystem general obj (lower bits)
- Bit 31 (
AT_DeadEnd): dead-end vs recovery - Bits 30-24: subsystem ID (e.g.
$01= exec,$02= graphics...) - Bits 23-16: general cause (
AG_*) - Bit 15: set for general alerts, clear for specific alerts
- Bits 14-0: object identifier (
AO_*) or subsystem-specific code
Deferred alerts and boot cycles¶
The display of a Guru is created by intuition.library. Deferred alerts may cause endless reboot cycles (the screen color cycling through all shades of gray) if a system module with an initialization priority higher than Intuition's fails and the problem persists across reboots. Many of the documented alert numbers may therefore never actually appear on screen.
Installing a custom trap handler¶
A trap handler is invoked via tc_TrapCode in supervisor mode. The exception vector number is on the top of the stack. Use RTE to return (after removing the vector number). To propagate to the previous handler, leave the vector on the stack.
void __regargs trapHandler(void); /* installed via tc_TrapCode */
SAS/C's startup module catch.o uses this mechanism for post-mortem dumps. The tc_TrapData field is officially unused but some handlers store private data there.
Bus errors: The A3000 sets a 250 ms bus time-out; in 1.3 mode, 8 ms with no bus error (accesses to nonexistent memory silently ignored). Gary also supports infinite time-out (currently unused).
See Also¶
Sources: Ralph Babel, "The Amiga Guru Book" (Taunusstein, 1993), Chapter 11 — Alerts, Gurus, and Traps.
Raw: raw/rkm/guru-book.md
Updated: 2026-08-08