2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Alert.Hook for AROS
10 #include <aros/debug.h>
11 #include <aros/config.h>
12 #include <exec/types.h>
13 #include <exec/resident.h>
14 #include <exec/alerts.h>
15 #include <exec/tasks.h>
16 #include <exec/execbase.h>
17 #include <intuition/intuitionbase.h>
18 #include <proto/exec.h>
19 #include <proto/intuition.h>
20 #include <aros/system.h>
21 #include <aros/libcall.h>
22 #include <aros/asmcall.h>
30 static const UBYTE Alerthook_name
[];
31 static const UBYTE Alerthook_version
[];
32 static AROS_UFP3(ULONG
, Alerthook_init
,
33 AROS_UFPA(void *, dummy1
, D0
),
34 AROS_UFPA(BPTR
, dummy2
, A0
),
35 AROS_UFPA(struct ExecBase
*, SysBase
, A6
)
37 static const char Alerthook_end
;
39 STRPTR
getGuruString(ULONG
, STRPTR
);
41 int Alerthook_entry(void)
43 /* If the hook was executed by accident return error code. */
47 const struct Resident Alerthook_resident
__attribute__((section(".text"))) =
50 (struct Resident
*)&Alerthook_resident
,
56 (UBYTE
*)Alerthook_name
,
57 (UBYTE
*)&Alerthook_version
[6],
58 (APTR
)&Alerthook_init
,
61 static const UBYTE Alerthook_name
[] = "alert.hook\r\n";
62 static const UBYTE Alerthook_version
[] = "$VER: alert.hook 41.8 (6.3.2001)";
63 static UBYTE
*const nomem
= "\x38\x0f" "Not Enough Memory! ";
64 static UBYTE
*const sfail
= "\x38\x0f" "Software Failure! ";
65 static UBYTE
*const recov
= "\x38\x0f" "Recoverable Alert! ";
66 static UBYTE
*const mouse
= "\x01\x50\x0f" "Press mouse button to continue.";
67 static UBYTE
*const fmtstring
= "\xa8\x2a" "Task: %08lx - ";
68 static UBYTE
*const errstring
= "\x1e" "Error %04x %04x - ";
69 static UBYTE
*const tasknotfound
= "--task not found--";
71 /* This is the callback for RawDoFmt() */
72 AROS_UFH2(void, putChProc
,
73 AROS_UFHA(UBYTE
, chr
, D0
),
74 AROS_UFHA(STRPTR
*, buf
, A3
))
84 /* This function copies a string, but also returns a pointer to the
85 '\0' at the end of the string. This way I can concat the strings
86 which have '\0' in them for other reasons.
88 Note len == -1 is equivalent to strcpy(dest,src).
91 mystrcpy(STRPTR dest
, STRPTR src
, LONG len
)
102 static AROS_UFH3(ULONG
, Alerthook_init
,
103 AROS_UFHA(void *, dummy1
, D0
),
104 AROS_UFHA(BPTR
, dummy2
, A0
),
105 AROS_UFHA(struct ExecBase
*, SysBase
, A6
)
110 #if (AROS_FLAVOUR & AROS_FLAVOUR_NATIVE)
112 Clear memory location zero (a cookie for the delayed guru after reset).
113 Some machines will keep putting a guru up during every reset if I don't
116 ULONG
*location_zero
= (void *)0;
121 D(bug("AlertHook: *******************\n"));
122 if(SysBase
->LastAlert
[0] != -1)
124 struct IntuitionBase
*IntuitionBase
;
126 UBYTE buffer
[256], *buf
, *tname
;
128 D(bug("alert.hook: LastAlert[0] = 0x%lx\n", SysBase
->LastAlert
[0]));
133 if(SysBase
->LastAlert
[0] & AG_NoMemory
)
134 buf
= mystrcpy(buf
, nomem
, -1);
135 else if(SysBase
->LastAlert
[0] & AT_DeadEnd
)
136 buf
= mystrcpy(buf
, sfail
, -1);
138 buf
= mystrcpy(buf
, recov
, -1);
142 buf
= mystrcpy(buf
, mouse
, -1);
143 *buf
++ = 1; *buf
++ = 0;
145 /* Find out the task name. The node type must be correct. */
146 task
= (struct Task
*)SysBase
->LastAlert
[1];
148 (task
->tc_Node
.ln_Type
== NT_TASK
)
149 || (task
->tc_Node
.ln_Type
== NT_PROCESS
)
151 && (task
->tc_Node
.ln_Name
!= NULL
)
153 tname
= task
->tc_Node
.ln_Name
;
155 tname
= tasknotfound
;
157 RawDoFmt(fmtstring
, &SysBase
->LastAlert
[1], (void *)putChProc
, &buf
);
158 buf
= mystrcpy(buf
- 1, tname
, 30);
159 *buf
++ = 1; *buf
++ = 0;
161 /* Use this variable to hold the current address */
163 RawDoFmt(errstring
, &SysBase
->LastAlert
[0], (void *)putChProc
, &buf
);
165 buf
= getGuruString(SysBase
->LastAlert
[0], &buf
[-1]);
168 /* This rather strange contraption will centre the string. */
169 *((UBYTE
*)tname
) = (82 - (buf
- tname
)) << 2;
171 IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library",0);
175 if(IntuitionBase
->LibNode
.lib_Version
>= 39)
176 TimedDisplayAlert(SysBase
->LastAlert
[0] & AT_DeadEnd
, buffer
, 0x38, 500);
178 DisplayAlert(SysBase
->LastAlert
[0] & AT_DeadEnd
, buffer
, 0x38);
180 CloseLibrary((struct Library
*)IntuitionBase
);
182 D(bug("alert.hook: No intuition, dumping message\n"));
183 D(bug("alert.hook: %s\n", buffer
));
186 SysBase
->LastAlert
[0] = -1;
189 SysBase
->LastAlert
[0] = old
;
190 SysBase
->LastAlert
[1] = NULL
;
197 /* Get a string from an array of type Errors. */
198 STRPTR
getString(STRPTR buffer
, ULONG alertnum
, const struct Errors
*errs
)
200 while((errs
->number
) && (errs
->number
!= alertnum
))
204 return mystrcpy(buffer
, errs
->string
, -1);
207 static const struct Errors cpustrings
[] =
209 { ACPU_BusErr
, "Hardware bus fault/address error" },
210 { ACPU_AddressErr
, "Illegal address access (odd)" },
211 { ACPU_InstErr
, "Illegal instruction" },
212 { ACPU_DivZero
, "Division by zero" },
213 { ACPU_CHK
, "CHK instruction error" },
214 { ACPU_TRAPV
, "TRAPV instruction error" },
215 { ACPU_PrivErr
, "Priviledge violation error" },
216 { ACPU_Trace
, "Trace error" },
217 { ACPU_LineA
, "Line 1010 (A) E mulator error" },
218 { ACPU_LineF
, "Line 1111 (F) Emulator/Coprocessor error" },
219 { ACPU_Format
, "Stack frame format error" },
220 { ACPU_Spurious
, "Spurious interrupt error" },
221 { 0, "Unknown CPU error" }
224 static const struct Errors subsystems
[] =
226 { 0x01, "exec.library " },
227 { 0x02, "graphics.library " },
228 { 0x03, "layers.library " },
229 { 0x04, "intuition.library " },
230 { 0x05, "math.library " },
231 { 0x07, "dos.library " },
233 { 0x09, "icon.library " },
234 { 0x0a, "expansion.library " },
235 { 0x0b, "diskfont.library " },
236 { 0x10, "audio.device " },
237 { 0x11, "console.device " },
238 { 0x12, "gameport.device " },
239 { 0x13, "keyboard.device " },
240 { 0x14, "trackdisk.device " },
241 { 0x15, "timer.device " },
242 { 0x20, "cia.resource " },
243 { 0x21, "disk.resource " },
244 { 0x22, "misc.resource " },
245 { 0x30, "bootstrap " },
246 { 0x31, "workbench " },
247 { 0x32, "diskcopy " },
248 { 0x33, "gadtools " },
249 { 0x34, "utility " },
255 /* This takes in 0x35 as well... */
259 static const struct Errors types
[] =
261 { 0x01, "no memory for " },
262 { 0x02, "could not make library " },
263 { 0x03, "could not open library " },
264 { 0x04, "could not open device " },
265 { 0x05, "could not open resource " },
266 { 0x06, "IO error with " },
267 { 0x07, "no signal for/from " },
268 { 0x08, "bad parameter for/from " },
269 { 0x09, "close library error with " },
270 { 0x0a, "close device error with " },
271 { 0x0b, "process creating failure with " },
272 { 0x00, "unknown problem with "}
275 static const struct Errors execstrings
[] =
277 { AN_ExcptVect
, "MC68k Exception vector checksum" },
278 { AN_BaseChkSum
, "ExecBase checksum" },
279 { AN_LibChkSum
, "Library checksum failure" },
280 { AN_MemCorrupt
, "Corrupt memory list detected" },
281 { AN_IntrMem
, "No memory for interrupt servers" },
282 { AN_InitAPtr
, "(obs) InitStruct of an APTR" },
283 { AN_SemCorrupt
, "Semaphore in an illegal state" },
284 { AN_FreeTwice
, "Memory freed twice" },
285 { AN_BogusExcpt
, "Illegal mc68k exception taken" },
286 { AN_IOUsedTwice
, "Attempt to reuse active IORequest" },
287 { AN_MemoryInsane
, "Sanity check on memory list failed" },
288 { AN_IOAfterClose
, "Attempt to use IORequest after close" },
289 { AN_StackProbe
, "Stack extends out of range" },
290 { AN_BadFreeAddr
, "Memory header not located" },
291 { AN_BadSemaphore
, "Attempt to use the old message semaphore" },
292 { 0, "unknown exec.library error" }
295 static const struct Errors gfxstrings
[] =
297 { AN_GfxNoMem
, "Graphics out of memory" },
298 { AN_GfxNoMemMspc
, "No memory to allocate MonitorSpec" },
299 { AN_LongFrame
, "No memory for long frame" },
300 { AN_ShortFrame
, "No memory for short frame" },
301 { AN_TextTmpRas
, "Mo memory for TmpRas" },
302 { AN_BltBitMap
, "No memory for BltBitMap" },
303 { AN_RegionMemory
, "No memory for Region" },
304 { AN_MakeVPort
, "No memory for MakeVPort" },
305 { AN_GfxNewError
, "Error in GfxNew()" },
306 { AN_GfxFreeError
, "Error in GfxFree()" },
307 { AN_GfxNoLCM
, "Emergency memory not available" },
308 { AN_ObsoleteFont
, "Unsupported font description used" },
309 { 0, "unknown graphics.library error" }
312 static const struct Errors unknownstrings
[] =
314 { 0, "unknown error" }
317 static const struct Errors layersstrings
[] =
319 { AN_LayersNoMem
, "layers: no memory" },
320 { 0, "unknown layers.library error" }
323 static const struct Errors intuistrings
[] =
325 { AN_GadgetType
, "intuition: unknown gadget type" },
326 { AN_CreatePort
, "intuition couldn't create port, no memory" },
327 { AN_ItemAlloc
, "no memory for menu item" },
328 { AN_SubAlloc
, "no memory for menu subitem" },
329 { AN_PlaneAlloc
, "no memory for bitplane" },
330 { AN_ItemBoxTop
, "top of item box < RelZero" },
331 { AN_OpenScreen
, "no memory for OpenScreen()" },
332 { AN_OpenScrnRast
, "no memory for OpenScreen() raster" },
333 { AN_SysScrnType
, "unknown type of system screen" },
334 { AN_AddSWGadget
, "add SW gadgets, no memory" },
335 { AN_OpenWindow
, "no memory for OpenWindow()" },
336 { AN_BadState
, "bad state return entering intuition" },
337 { AN_BadMessage
, "bad message received by IDCMP" },
338 { AN_WeirdEcho
, "weird echo causing incomprehension" },
339 { AN_NoConsole
, "couldn't open the console.device" },
340 { AN_NoISem
, "intuition skipped obtaining a semaphore" },
341 { AN_ISemOrder
, "intuition got a semaphore in wrong order" },
342 { 0, "unknown intuition.library error" }
345 static const struct Errors mathstrings
[] =
347 { 0, "unknown math library error" }
350 static const struct Errors dosstrings
[] =
352 { AN_StartMem
, "no memory at startup" },
353 { AN_EndTask
, "EndTask did not end task" },
354 { AN_QPktFail
, "QPkt failure" },
355 { AN_AsyncPkt
, "unexpected DOS packet received" },
356 { AN_FreeVec
, "freevec failed" },
357 { AN_DiskBlkSeq
, "disk block sequence error" },
358 { AN_BitMap
, "disk bitmap corrupt" },
359 { AN_KeyFree
, "disk key already free" },
360 { AN_BadChkSum
, "disk checksum bad" },
361 { AN_DiskError
, "disk error" },
362 { AN_KeyRange
, "disk key out of range" },
363 { AN_BadOverlay
, "bad overlay" },
364 { AN_BadInitFunc
, "invalid initialization packet for cli/shell" },
365 { AN_FileReclosed
, "filehandle closed more than once" },
366 { 0, "unknown dos.library error" }
369 static const struct Errors ramlibstrings
[] =
371 { AN_BadSegList
, "bad library seglist" },
372 { 0, "unknown ramlib/lddemon error" }
375 static const struct Errors iconstrings
[] =
377 { 0, "unknown icon.library error" }
380 static const struct Errors expanstrings
[] =
382 { AN_BadExpansionFree
, "expansion freeing region already freed"},
383 { 0, "unknown expansion.library error" }
386 static const struct Errors utilitystrings
[] =
388 {0, "unknown utility.library error" }
391 static const struct Errors keymapstrings
[] =
393 {0, "unknown keymap error" }
396 static const struct Errors dfontstrings
[] =
398 { 0, "unknown diskfont.library error" }
401 static const struct Errors audiostrings
[] =
403 { 0, "unknown audio.device error" }
406 static const struct Errors consolestrings
[] =
408 { AN_NoWindow
, "can't open initial console window" },
409 { 0, "unknown console.device error" }
412 static const struct Errors gameportstrings
[] =
414 { 0, "unknown gameport.device error" }
417 static const struct Errors keyboardstrings
[] =
419 { 0, "unknown keyboard.device error" }
422 static const struct Errors trackdiskstrings
[] =
424 { AN_TDCalibSeek
, "trackdisk calibrate seek error" },
425 { 0, "unknown trackdisk.device error" }
428 static const struct Errors timerstrings
[] =
430 { AN_TMBadReq
, "bad timer request" },
431 { AN_TMBadSupply
, "bad timer powersupply frequency" },
432 { 0, "unknown timer.device error" }
435 static const struct Errors ciastrings
[] =
437 { 0, "unknown cia resource error" }
440 static const struct Errors diskstrings
[] =
442 { AN_DRHasDisk
, "get disk unit, already has disk" },
443 { AN_DRIntNoAct
,"disk interrupt, no active unit" },
444 { 0, "unknown disk.resource error" }
447 static const struct Errors miscstrings
[] =
449 { 0, "unknown misc.resource error" }
452 static const struct Errors bootstrings
[] =
454 { AN_BootError
, "boot code returned an error" },
455 { 0, "unknown bootstrap error" }
458 static const struct Errors workbenchstrings
[] =
460 { AN_NoFonts
, "no fonts for workbench" },
461 { AN_WBBadStartupMsg1
, "bad startup message 1 for workbench" },
462 { AN_WBBadStartupMsg2
, "bad startup message 2 for workbench" },
463 { AN_WBBadIOMsg
, "bad IO message for workbench" },
464 { AN_WBReLayoutToolMenu
, "error with layout on tools menu" },
465 { 0, "unknown workbench error" }
468 static const struct Errors diskcopystrings
[] =
470 {0, "unknown diskcopy error" }
473 static const struct Errors gadtoolsstrings
[] =
475 {0, "unknown gadtools.library error" }
478 static const struct Errors arosstrings
[] =
480 {0, "unknown aros.library error" }
483 static const struct Errors oopstrings
[] =
485 {0, "unknown oop.library error" }
488 static const struct Errors hiddstrings
[] =
490 {0, "unknown Hidd system error" }
493 static const struct Errors
*const stringlist
[] =
573 /* Decode the alert number, and try and work out what string to get */
574 STRPTR
getGuruString(ULONG alertnum
, STRPTR buf
)
576 /* Is this a CPU alert? */
577 if((alertnum
& 0x7f008000) == 0)
580 buf
= getString(buf
, alertnum
, cpustrings
);
582 /* Is this a General alert */
583 else if((alertnum
& 0x8000) == 0x8000)
585 UBYTE type
= (alertnum
& 0x00FF0000) >> 16;
586 UWORD obj
= (alertnum
& 0x7fff);
587 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
589 buf
= getString(buf
, obj
, subsystems
);
590 buf
= getString(&buf
[-1], type
, types
);
591 buf
= getString(&buf
[-1], subsys
, subsystems
);
593 /* This must be a specific alert */
596 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
599 buf
= getString(buf
, alertnum
, stringlist
[subsys
]);
601 buf
= mystrcpy(buf
, "unknown error", -1);
607 static const char Alerthook_end
= 1;