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
)
38 STRPTR
getGuruString(ULONG
, STRPTR
);
40 extern void Alerthook_end(void);
42 const struct Resident Alerthook_resident
=
45 (struct Resident
*)&Alerthook_resident
,
51 (UBYTE
*)Alerthook_name
,
52 (UBYTE
*)&Alerthook_version
[6],
53 (APTR
)&Alerthook_init
,
56 static const UBYTE Alerthook_name
[] = "alert.hook\r\n";
57 static const UBYTE Alerthook_version
[] = "$VER: alert.hook 41.8 " ADATE
;
58 static UBYTE
*const nomem
= "\x38\x0f" "Not Enough Memory! ";
59 static UBYTE
*const sfail
= "\x38\x0f" "Software Failure! ";
60 static UBYTE
*const recov
= "\x38\x0f" "Recoverable Alert! ";
61 static UBYTE
*const mouse
= "\x01\x50\x0f" "Press mouse button to continue.";
62 static UBYTE
*const fmtstring
= "\xa8\x2a" "Task: %08lx - ";
63 static UBYTE
*const errstring
= "\x1e" "Error %04x %04x - ";
64 static UBYTE
*const tasknotfound
= "--task not found--";
66 /* This is the callback for RawDoFmt() */
67 AROS_UFH2(void, putChProc
,
68 AROS_UFHA(UBYTE
, chr
, D0
),
69 AROS_UFHA(STRPTR
*, buf
, A3
))
79 /* This function copies a string, but also returns a pointer to the
80 '\0' at the end of the string. This way I can concat the strings
81 which have '\0' in them for other reasons.
83 Note len == -1 is equivalent to strcpy(dest,src).
86 mystrcpy(STRPTR dest
, STRPTR src
, LONG len
)
97 static AROS_UFH3(ULONG
, Alerthook_init
,
98 AROS_UFHA(void *, dummy1
, D0
),
99 AROS_UFHA(BPTR
, dummy2
, A0
),
100 AROS_UFHA(struct ExecBase
*, SysBase
, A6
)
105 #if (AROS_FLAVOUR & AROS_FLAVOUR_NATIVE)
107 Clear memory location zero (a cookie for the delayed guru after reset).
108 Some machines will keep putting a guru up during every reset if I don't
111 ULONG
*location_zero
= (void *)0;
116 D(bug("AlertHook: *******************\n"));
117 if(SysBase
->LastAlert
[0] != -1)
119 struct IntuitionBase
*IntuitionBase
;
121 UBYTE buffer
[256], *buf
, *tname
;
123 D(bug("alert.hook: LastAlert[0] = 0x%lx\n", SysBase
->LastAlert
[0]));
128 if(SysBase
->LastAlert
[0] & AG_NoMemory
)
129 buf
= mystrcpy(buf
, nomem
, -1);
130 else if(SysBase
->LastAlert
[0] & AT_DeadEnd
)
131 buf
= mystrcpy(buf
, sfail
, -1);
133 buf
= mystrcpy(buf
, recov
, -1);
137 buf
= mystrcpy(buf
, mouse
, -1);
138 *buf
++ = 1; *buf
++ = 0;
140 /* Find out the task name. The node type must be correct. */
141 task
= (struct Task
*)SysBase
->LastAlert
[1];
143 (task
->tc_Node
.ln_Type
== NT_TASK
)
144 || (task
->tc_Node
.ln_Type
== NT_PROCESS
)
146 && (task
->tc_Node
.ln_Name
!= NULL
)
148 tname
= task
->tc_Node
.ln_Name
;
150 tname
= tasknotfound
;
152 RawDoFmt(fmtstring
, &SysBase
->LastAlert
[1], (void *)putChProc
, &buf
);
153 buf
= mystrcpy(buf
- 1, tname
, 30);
154 *buf
++ = 1; *buf
++ = 0;
156 /* Use this variable to hold the current address */
158 RawDoFmt(errstring
, &SysBase
->LastAlert
[0], (void *)putChProc
, &buf
);
160 buf
= getGuruString(SysBase
->LastAlert
[0], &buf
[-1]);
163 /* This rather strange contraption will centre the string. */
164 *((UBYTE
*)tname
) = (82 - (buf
- tname
)) << 2;
166 IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library",0);
170 if(IntuitionBase
->LibNode
.lib_Version
>= 39)
171 TimedDisplayAlert(SysBase
->LastAlert
[0] & AT_DeadEnd
, buffer
, 0x38, 500);
173 DisplayAlert(SysBase
->LastAlert
[0] & AT_DeadEnd
, buffer
, 0x38);
175 CloseLibrary((struct Library
*)IntuitionBase
);
177 D(bug("alert.hook: No intuition, dumping message\n"));
178 D(bug("alert.hook: %s\n", buffer
));
181 SysBase
->LastAlert
[0] = -1;
184 SysBase
->LastAlert
[0] = old
;
185 SysBase
->LastAlert
[1] = NULL
;
192 /* Get a string from an array of type Errors. */
193 STRPTR
getString(STRPTR buffer
, ULONG alertnum
, const struct Errors
*errs
)
195 while((errs
->number
) && (errs
->number
!= alertnum
))
199 return mystrcpy(buffer
, errs
->string
, -1);
202 static const struct Errors cpustrings
[] =
204 { ACPU_BusErr
, "Hardware bus fault/address error" },
205 { ACPU_AddressErr
, "Illegal address access (odd)" },
206 { ACPU_InstErr
, "Illegal instruction" },
207 { ACPU_DivZero
, "Division by zero" },
208 { ACPU_CHK
, "CHK instruction error" },
209 { ACPU_TRAPV
, "TRAPV instruction error" },
210 { ACPU_PrivErr
, "Priviledge violation error" },
211 { ACPU_Trace
, "Trace error" },
212 { ACPU_LineA
, "Line 1010 (A) E mulator error" },
213 { ACPU_LineF
, "Line 1111 (F) Emulator/Coprocessor error" },
214 { ACPU_Format
, "Stack frame format error" },
215 { ACPU_Spurious
, "Spurious interrupt error" },
216 { 0, "Unknown CPU error" }
219 static const struct Errors subsystems
[] =
221 { 0x01, "exec.library " },
222 { 0x02, "graphics.library " },
223 { 0x03, "layers.library " },
224 { 0x04, "intuition.library " },
225 { 0x05, "math.library " },
226 { 0x07, "dos.library " },
228 { 0x09, "icon.library " },
229 { 0x0a, "expansion.library " },
230 { 0x0b, "diskfont.library " },
231 { 0x10, "audio.device " },
232 { 0x11, "console.device " },
233 { 0x12, "gameport.device " },
234 { 0x13, "keyboard.device " },
235 { 0x14, "trackdisk.device " },
236 { 0x15, "timer.device " },
237 { 0x20, "cia.resource " },
238 { 0x21, "disk.resource " },
239 { 0x22, "misc.resource " },
240 { 0x30, "bootstrap " },
241 { 0x31, "workbench " },
242 { 0x32, "diskcopy " },
243 { 0x33, "gadtools " },
244 { 0x34, "utility " },
250 /* This takes in 0x35 as well... */
254 static const struct Errors types
[] =
256 { 0x01, "no memory for " },
257 { 0x02, "could not make library " },
258 { 0x03, "could not open library " },
259 { 0x04, "could not open device " },
260 { 0x05, "could not open resource " },
261 { 0x06, "IO error with " },
262 { 0x07, "no signal for/from " },
263 { 0x08, "bad parameter for/from " },
264 { 0x09, "close library error with " },
265 { 0x0a, "close device error with " },
266 { 0x0b, "process creating failure with " },
267 { 0x00, "unknown problem with "}
270 static const struct Errors execstrings
[] =
272 { AN_ExcptVect
, "MC68k Exception vector checksum" },
273 { AN_BaseChkSum
, "ExecBase checksum" },
274 { AN_LibChkSum
, "Library checksum failure" },
275 { AN_MemCorrupt
, "Corrupt memory list detected" },
276 { AN_IntrMem
, "No memory for interrupt servers" },
277 { AN_InitAPtr
, "(obs) InitStruct of an APTR" },
278 { AN_SemCorrupt
, "Semaphore in an illegal state" },
279 { AN_FreeTwice
, "Memory freed twice" },
280 { AN_BogusExcpt
, "Illegal mc68k exception taken" },
281 { AN_IOUsedTwice
, "Attempt to reuse active IORequest" },
282 { AN_MemoryInsane
, "Sanity check on memory list failed" },
283 { AN_IOAfterClose
, "Attempt to use IORequest after close" },
284 { AN_StackProbe
, "Stack extends out of range" },
285 { AN_BadFreeAddr
, "Memory header not located" },
286 { AN_BadSemaphore
, "Attempt to use the old message semaphore" },
287 { 0, "unknown exec.library error" }
290 static const struct Errors gfxstrings
[] =
292 { AN_GfxNoMem
, "Graphics out of memory" },
293 { AN_GfxNoMemMspc
, "No memory to allocate MonitorSpec" },
294 { AN_LongFrame
, "No memory for long frame" },
295 { AN_ShortFrame
, "No memory for short frame" },
296 { AN_TextTmpRas
, "Mo memory for TmpRas" },
297 { AN_BltBitMap
, "No memory for BltBitMap" },
298 { AN_RegionMemory
, "No memory for Region" },
299 { AN_MakeVPort
, "No memory for MakeVPort" },
300 { AN_GfxNewError
, "Error in GfxNew()" },
301 { AN_GfxFreeError
, "Error in GfxFree()" },
302 { AN_GfxNoLCM
, "Emergency memory not available" },
303 { AN_ObsoleteFont
, "Unsupported font description used" },
304 { 0, "unknown graphics.library error" }
307 static const struct Errors unknownstrings
[] =
309 { 0, "unknown error" }
312 static const struct Errors layersstrings
[] =
314 { AN_LayersNoMem
, "layers: no memory" },
315 { 0, "unknown layers.library error" }
318 static const struct Errors intuistrings
[] =
320 { AN_GadgetType
, "intuition: unknown gadget type" },
321 { AN_CreatePort
, "intuition couldn't create port, no memory" },
322 { AN_ItemAlloc
, "no memory for menu item" },
323 { AN_SubAlloc
, "no memory for menu subitem" },
324 { AN_PlaneAlloc
, "no memory for bitplane" },
325 { AN_ItemBoxTop
, "top of item box < RelZero" },
326 { AN_OpenScreen
, "no memory for OpenScreen()" },
327 { AN_OpenScrnRast
, "no memory for OpenScreen() raster" },
328 { AN_SysScrnType
, "unknown type of system screen" },
329 { AN_AddSWGadget
, "add SW gadgets, no memory" },
330 { AN_OpenWindow
, "no memory for OpenWindow()" },
331 { AN_BadState
, "bad state return entering intuition" },
332 { AN_BadMessage
, "bad message received by IDCMP" },
333 { AN_WeirdEcho
, "weird echo causing incomprehension" },
334 { AN_NoConsole
, "couldn't open the console.device" },
335 { AN_NoISem
, "intuition skipped obtaining a semaphore" },
336 { AN_ISemOrder
, "intuition got a semaphore in wrong order" },
337 { 0, "unknown intuition.library error" }
340 static const struct Errors mathstrings
[] =
342 { 0, "unknown math library error" }
345 static const struct Errors dosstrings
[] =
347 { AN_StartMem
, "no memory at startup" },
348 { AN_EndTask
, "EndTask did not end task" },
349 { AN_QPktFail
, "QPkt failure" },
350 { AN_AsyncPkt
, "unexpected DOS packet received" },
351 { AN_FreeVec
, "freevec failed" },
352 { AN_DiskBlkSeq
, "disk block sequence error" },
353 { AN_BitMap
, "disk bitmap corrupt" },
354 { AN_KeyFree
, "disk key already free" },
355 { AN_BadChkSum
, "disk checksum bad" },
356 { AN_DiskError
, "disk error" },
357 { AN_KeyRange
, "disk key out of range" },
358 { AN_BadOverlay
, "bad overlay" },
359 { AN_BadInitFunc
, "invalid initialization packet for cli/shell" },
360 { AN_FileReclosed
, "filehandle closed more than once" },
361 { 0, "unknown dos.library error" }
364 static const struct Errors ramlibstrings
[] =
366 { AN_BadSegList
, "bad library seglist" },
367 { 0, "unknown ramlib/lddemon error" }
370 static const struct Errors iconstrings
[] =
372 { 0, "unknown icon.library error" }
375 static const struct Errors expanstrings
[] =
377 { AN_BadExpansionFree
, "expansion freeing region already freed"},
378 { 0, "unknown expansion.library error" }
381 static const struct Errors utilitystrings
[] =
383 {0, "unknown utility.library error" }
386 static const struct Errors keymapstrings
[] =
388 {0, "unknown keymap error" }
391 static const struct Errors dfontstrings
[] =
393 { 0, "unknown diskfont.library error" }
396 static const struct Errors audiostrings
[] =
398 { 0, "unknown audio.device error" }
401 static const struct Errors consolestrings
[] =
403 { AN_NoWindow
, "can't open initial console window" },
404 { 0, "unknown console.device error" }
407 static const struct Errors gameportstrings
[] =
409 { 0, "unknown gameport.device error" }
412 static const struct Errors keyboardstrings
[] =
414 { 0, "unknown keyboard.device error" }
417 static const struct Errors trackdiskstrings
[] =
419 { AN_TDCalibSeek
, "trackdisk calibrate seek error" },
420 { 0, "unknown trackdisk.device error" }
423 static const struct Errors timerstrings
[] =
425 { AN_TMBadReq
, "bad timer request" },
426 { AN_TMBadSupply
, "bad timer powersupply frequency" },
427 { 0, "unknown timer.device error" }
430 static const struct Errors ciastrings
[] =
432 { 0, "unknown cia resource error" }
435 static const struct Errors diskstrings
[] =
437 { AN_DRHasDisk
, "get disk unit, already has disk" },
438 { AN_DRIntNoAct
,"disk interrupt, no active unit" },
439 { 0, "unknown disk.resource error" }
442 static const struct Errors miscstrings
[] =
444 { 0, "unknown misc.resource error" }
447 static const struct Errors bootstrings
[] =
449 { AN_BootError
, "boot code returned an error" },
450 { 0, "unknown bootstrap error" }
453 static const struct Errors workbenchstrings
[] =
455 { AN_NoFonts
, "no fonts for workbench" },
456 { AN_WBBadStartupMsg1
, "bad startup message 1 for workbench" },
457 { AN_WBBadStartupMsg2
, "bad startup message 2 for workbench" },
458 { AN_WBBadIOMsg
, "bad IO message for workbench" },
459 { AN_WBReLayoutToolMenu
, "error with layout on tools menu" },
460 { 0, "unknown workbench error" }
463 static const struct Errors diskcopystrings
[] =
465 {0, "unknown diskcopy error" }
468 static const struct Errors gadtoolsstrings
[] =
470 {0, "unknown gadtools.library error" }
473 static const struct Errors arosstrings
[] =
475 {0, "unknown aros.library error" }
478 static const struct Errors oopstrings
[] =
480 {0, "unknown oop.library error" }
483 static const struct Errors hiddstrings
[] =
485 {0, "unknown Hidd system error" }
488 static const struct Errors
*const stringlist
[] =
568 /* Decode the alert number, and try and work out what string to get */
569 STRPTR
getGuruString(ULONG alertnum
, STRPTR buf
)
571 /* Is this a CPU alert? */
572 if((alertnum
& 0x7f008000) == 0)
575 buf
= getString(buf
, alertnum
, cpustrings
);
577 /* Is this a General alert */
578 else if((alertnum
& 0x8000) == 0x8000)
580 UBYTE type
= (alertnum
& 0x00FF0000) >> 16;
581 UWORD obj
= (alertnum
& 0x7fff);
582 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
584 buf
= getString(buf
, obj
, subsystems
);
585 buf
= getString(&buf
[-1], type
, types
);
586 buf
= getString(&buf
[-1], subsys
, subsystems
);
588 /* This must be a specific alert */
591 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
594 buf
= getString(buf
, alertnum
, stringlist
[subsys
]);
596 buf
= mystrcpy(buf
, "unknown error", -1);