simplerexx updated:
[AROS.git] / rom / exec / alertstrings.c
blob80cbcdcd5403827dc626620dd9b29b4b706fe425
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
7 * A library of alert strings and useful functions.
8 * Used by platform-specific Alert() implementations
9 */
11 #include <aros/debug.h>
12 #include <exec/alerts.h>
13 #include <exec/rawfmt.h>
14 #include <exec/tasks.h>
15 #include <libraries/debug.h>
16 #include <proto/debug.h>
17 #include <proto/kernel.h>
19 #include "etask.h"
20 #include "exec_intern.h"
21 #include "exec_util.h"
23 struct Errors
25 ULONG number;
26 STRPTR string;
29 /* Get a string from an array of type Errors. */
30 static STRPTR getString(ULONG alertnum, const struct Errors *errs)
32 /* Some of alert codes have AT_DeadEnd bit set, others have it reset.
33 However in real life AT_DeadEnd bit may be set for any error, so
34 we mask it out for comparison */
35 alertnum &= ~AT_DeadEnd;
37 while((errs->number) && ((errs->number & ~AT_DeadEnd) != alertnum))
39 errs++;
41 return errs->string;
44 static const struct Errors cpustrings[] =
46 { ACPU_BusErr, "Hardware bus fault/address error" },
47 { ACPU_AddressErr, "Illegal address access" },
48 { ACPU_InstErr, "Illegal instruction" },
49 { ACPU_DivZero, "Division by zero" },
50 { ACPU_CHK, "CHK instruction error" },
51 { ACPU_TRAPV, "TRAPV instruction error" },
52 { ACPU_PrivErr, "Privilege violation error" },
53 { ACPU_Trace, "Trace error" },
54 { ACPU_LineA, "Line 1010 (A) E mulator error" },
55 { ACPU_LineF, "Line 1111 (F) Emulator/Coprocessor error" },
56 { ACPU_Format, "Stack frame format error" },
57 { ACPU_Spurious, "Spurious interrupt error" },
58 { 0, "Unknown CPU error" }
61 static const struct Errors subsystems[] =
63 { 0x01, "exec.library " },
64 { 0x02, "graphics.library " },
65 { 0x03, "layers.library " },
66 { 0x04, "intuition.library " },
67 { 0x05, "math.library " },
68 { 0x07, "dos.library " },
69 { 0x08, "ramlib " },
70 { 0x09, "icon.library " },
71 { 0x0a, "expansion.library " },
72 { 0x0b, "diskfont.library " },
73 { 0x10, "audio.device " },
74 { 0x11, "console.device " },
75 { 0x12, "gameport.device " },
76 { 0x13, "keyboard.device " },
77 { 0x14, "trackdisk.device " },
78 { 0x15, "timer.device " },
79 { 0x20, "cia.resource " },
80 { 0x21, "disk.resource " },
81 { 0x22, "misc.resource " },
82 { 0x30, "bootstrap " },
83 { 0x31, "workbench " },
84 { 0x32, "diskcopy " },
85 { 0x33, "gadtools " },
86 { 0x34, "utility " },
88 { 0x40, "aros " },
89 { 0x41, "oop " },
90 { 0x42, "hidd " },
91 { 0x43, "partition.library " },
93 /* This takes in 0x35 as well... */
94 { 0x00, "unknown " }
97 static const struct Errors types[] =
99 { 0x01, "no memory for " },
100 { 0x02, "could not make library " },
101 { 0x03, "could not open library " },
102 { 0x04, "could not open device " },
103 { 0x05, "could not open resource " },
104 { 0x06, "IO error with " },
105 { 0x07, "no signal for/from " },
106 { 0x08, "bad parameter for/from " },
107 { 0x09, "close library error with " },
108 { 0x0a, "close device error with " },
109 { 0x0b, "process creating failure with " },
110 { 0x00, "unknown problem with "}
113 static const struct Errors execstrings[] =
115 { AN_ExcptVect, "MC68k Exception vector checksum" },
116 { AN_BaseChkSum, "ExecBase checksum" },
117 { AN_LibChkSum, "Library checksum failure" },
118 { AN_MemCorrupt, "Corrupt memory list detected" },
119 { AN_IntrMem, "No memory for interrupt servers" },
120 { AN_InitAPtr, "(obs) InitStruct of an APTR" },
121 { AN_SemCorrupt, "Semaphore in an illegal state" },
122 { AN_FreeTwice, "Memory freed twice" },
123 { AN_BogusExcpt, "Illegal mc68k exception taken" },
124 { AN_IOUsedTwice, "Attempt to reuse active IORequest" },
125 { AN_MemoryInsane, "Sanity check on memory list failed" },
126 { AN_IOAfterClose, "Attempt to use IORequest after close" },
127 { AN_StackProbe, "Stack extends out of range" },
128 { AN_BadFreeAddr, "Memory header not located" },
129 { AN_BadSemaphore, "Attempt to use the old message semaphore" },
130 { 0, "unknown exec.library error" }
133 static const struct Errors gfxstrings[] =
135 { AN_GfxNoMem, "Graphics out of memory" },
136 { AN_GfxNoMemMspc, "No memory to allocate MonitorSpec" },
137 { AN_LongFrame, "No memory for long frame" },
138 { AN_ShortFrame, "No memory for short frame" },
139 { AN_TextTmpRas, "Mo memory for TmpRas" },
140 { AN_BltBitMap, "No memory for BltBitMap" },
141 { AN_RegionMemory, "No memory for Region" },
142 { AN_MakeVPort, "No memory for MakeVPort" },
143 { AN_GfxNewError, "Error in GfxNew()" },
144 { AN_GfxFreeError, "Error in GfxFree()" },
145 { AN_GfxNoLCM, "Emergency memory not available" },
146 { AN_ObsoleteFont, "Unsupported font description used" },
147 { 0, "unknown graphics.library error" }
150 static const struct Errors unknownstrings[] =
152 { 0, "unknown error" }
155 static const struct Errors layersstrings[] =
157 { AN_LayersNoMem, "layers: no memory" },
158 { 0, "unknown layers.library error" }
161 static const struct Errors intuistrings[] =
163 { AN_GadgetType, "intuition: unknown gadget type" },
164 { AN_CreatePort, "intuition couldn't create port, no memory" },
165 { AN_ItemAlloc, "no memory for menu item" },
166 { AN_SubAlloc, "no memory for menu subitem" },
167 { AN_PlaneAlloc, "no memory for bitplane" },
168 { AN_ItemBoxTop, "top of item box < RelZero" },
169 { AN_OpenScreen, "no memory for OpenScreen()" },
170 { AN_OpenScrnRast, "no memory for OpenScreen() raster" },
171 { AN_SysScrnType, "unknown type of system screen" },
172 { AN_AddSWGadget, "add SW gadgets, no memory" },
173 { AN_OpenWindow, "no memory for OpenWindow()" },
174 { AN_BadState, "bad state return entering intuition" },
175 { AN_BadMessage, "bad message received by IDCMP" },
176 { AN_WeirdEcho, "weird echo causing incomprehension" },
177 { AN_NoConsole, "couldn't open the console.device" },
178 { AN_NoISem, "intuition skipped obtaining a semaphore" },
179 { AN_ISemOrder, "intuition got a semaphore in wrong order" },
180 { 0, "unknown intuition.library error" }
183 static const struct Errors mathstrings[] =
185 { 0, "unknown math library error" }
188 static const struct Errors dosstrings[] =
190 { AN_StartMem, "no memory at startup" },
191 { AN_EndTask, "EndTask did not end task" },
192 { AN_QPktFail, "QPkt failure" },
193 { AN_AsyncPkt, "unexpected DOS packet received" },
194 { AN_FreeVec, "freevec failed" },
195 { AN_DiskBlkSeq, "disk block sequence error" },
196 { AN_BitMap, "disk bitmap corrupt" },
197 { AN_KeyFree, "disk key already free" },
198 { AN_BadChkSum, "disk checksum bad" },
199 { AN_DiskError, "disk error" },
200 { AN_KeyRange, "disk key out of range" },
201 { AN_BadOverlay, "bad overlay" },
202 { AN_BadInitFunc, "invalid initialization packet for cli/shell" },
203 { AN_FileReclosed, "filehandle closed more than once" },
204 { 0, "unknown dos.library error" }
207 static const struct Errors ramlibstrings[] =
209 { AN_BadSegList, "bad library seglist" },
210 { 0, "unknown ramlib/lddemon error" }
213 static const struct Errors iconstrings[] =
215 { 0, "unknown icon.library error" }
218 static const struct Errors expanstrings[] =
220 { AN_BadExpansionFree, "expansion freeing region already freed"},
221 { 0, "unknown expansion.library error" }
224 static const struct Errors utilitystrings[] =
226 {0, "unknown utility.library error" }
229 static const struct Errors keymapstrings[] =
231 {0, "unknown keymap error" }
234 static const struct Errors dfontstrings[] =
236 { 0, "unknown diskfont.library error" }
239 static const struct Errors audiostrings[] =
241 { 0, "unknown audio.device error" }
244 static const struct Errors consolestrings[] =
246 { AN_NoWindow, "can't open initial console window" },
247 { 0, "unknown console.device error" }
250 static const struct Errors gameportstrings[] =
252 { 0, "unknown gameport.device error" }
255 static const struct Errors keyboardstrings[] =
257 { 0, "unknown keyboard.device error" }
260 static const struct Errors trackdiskstrings[] =
262 { AN_TDCalibSeek, "trackdisk calibrate seek error" },
263 { 0, "unknown trackdisk.device error" }
266 static const struct Errors timerstrings[] =
268 { AN_TMBadReq, "bad timer request" },
269 { AN_TMBadSupply, "bad timer powersupply frequency" },
270 { 0, "unknown timer.device error" }
273 static const struct Errors ciastrings[] =
275 { 0, "unknown cia resource error" }
278 static const struct Errors diskstrings[] =
280 { AN_DRHasDisk, "get disk unit, already has disk" },
281 { AN_DRIntNoAct,"disk interrupt, no active unit" },
282 { 0, "unknown disk.resource error" }
285 static const struct Errors miscstrings[] =
287 { 0, "unknown misc.resource error" }
290 static const struct Errors bootstrings[] =
292 { AN_BootError, "boot code returned an error" },
293 { 0, "unknown bootstrap error" }
296 static const struct Errors workbenchstrings[] =
298 { AN_NoFonts, "no fonts for workbench" },
299 { AN_WBBadStartupMsg1, "bad startup message 1 for workbench" },
300 { AN_WBBadStartupMsg2, "bad startup message 2 for workbench" },
301 { AN_WBBadIOMsg, "bad IO message for workbench" },
302 { AN_WBReLayoutToolMenu, "error with layout on tools menu" },
303 { 0, "unknown workbench error" }
306 static const struct Errors diskcopystrings[] =
308 {0, "unknown diskcopy error" }
311 static const struct Errors gadtoolsstrings[] =
313 {0, "unknown gadtools.library error" }
316 static const struct Errors arosstrings[] =
318 {0, "unknown aros.library error" }
321 static const struct Errors oopstrings[] =
323 {0, "unknown oop.library error" }
326 static const struct Errors hiddstrings[] =
328 {0, "unknown Hidd system error" }
331 static const struct Errors partitionstrings[] =
333 {0, "unknown partition.library error" }
336 static const struct Errors *const stringlist[] =
338 /* 0x00 */
339 unknownstrings,
340 execstrings,
341 gfxstrings,
342 layersstrings,
343 intuistrings,
344 mathstrings,
345 unknownstrings,
346 dosstrings,
347 ramlibstrings,
348 iconstrings,
349 expanstrings,
350 dfontstrings,
351 utilitystrings,
352 keymapstrings,
353 unknownstrings,
354 unknownstrings,
356 /* 0x10 */
357 audiostrings,
358 consolestrings,
359 gameportstrings,
360 keyboardstrings,
361 trackdiskstrings,
362 timerstrings,
363 unknownstrings,
364 unknownstrings,
365 unknownstrings,
366 unknownstrings,
367 unknownstrings,
368 unknownstrings,
369 unknownstrings,
370 unknownstrings,
371 unknownstrings,
372 unknownstrings,
374 /* 0x20 */
375 ciastrings,
376 diskstrings,
377 miscstrings,
378 unknownstrings,
379 unknownstrings,
380 unknownstrings,
381 unknownstrings,
382 unknownstrings,
383 unknownstrings,
384 unknownstrings,
385 unknownstrings,
386 unknownstrings,
387 unknownstrings,
388 unknownstrings,
389 unknownstrings,
390 unknownstrings,
392 /* 0x30 */
393 bootstrings,
394 workbenchstrings,
395 diskcopystrings,
396 gadtoolsstrings,
397 unknownstrings,
398 unknownstrings,
399 unknownstrings,
400 unknownstrings,
401 unknownstrings,
402 unknownstrings,
403 unknownstrings,
404 unknownstrings,
405 unknownstrings,
406 unknownstrings,
407 unknownstrings,
408 unknownstrings,
410 /* 0x40 */
411 arosstrings,
412 oopstrings,
413 hiddstrings,
414 partitionstrings
417 /* Similar to strcpy() but returns a pointer to the next byte beyond the
418 copied string. Useful for concatenation. */
419 STRPTR Alert_AddString(STRPTR dest, CONST_STRPTR src)
421 while(*src)
423 *dest++ = *src++;
425 return dest;
428 STRPTR Alert_GetTitle(ULONG alertNum)
430 if((alertNum & 0x00ff0000) == AG_NoMemory)
431 return "Not Enough Memory!";
432 else if(alertNum & AT_DeadEnd)
433 return "Software Failure!";
434 else
435 return "Recoverable Alert!";
438 /* Decode the alert number, and try and work out what string to get */
439 STRPTR Alert_GetString(ULONG alertnum, STRPTR buf)
441 /* Is this a CPU alert? */
442 if((alertnum & 0x7f008000) == 0)
444 /* Yes */
445 buf = Alert_AddString(buf, getString(alertnum, cpustrings));
447 /* Is this a General alert */
448 else if((alertnum & 0x8000) == 0x8000)
450 UBYTE type = (alertnum & 0x00FF0000) >> 16;
451 UWORD obj = (alertnum & 0x7fff);
452 UBYTE subsys = (alertnum & 0x7f000000) >> 24;
454 buf = Alert_AddString(buf, getString(obj, subsystems));
455 buf = Alert_AddString(buf, getString(type, types));
456 buf = Alert_AddString(buf, getString(subsys, subsystems));
458 /* This must be a specific alert */
459 else
461 UBYTE subsys = (alertnum & 0x7f000000) >> 24;
463 buf = Alert_AddString(buf, getString(alertnum, stringlist[subsys]));
466 *buf = 0;
467 return buf;
470 static const char hdrstring[] = "Task : 0x%P - %s";
471 static const char errstring[] = "\nError: 0x%08lx - ";
472 static const char locstring[] = "\nPC : 0x%P";
473 static const char stkstring[] = "\nStack: 0x%P - 0x%P";
475 STRPTR FormatAlert(char *buffer, ULONG alertNum, struct Task *task, APTR location, UBYTE type, struct ExecBase *SysBase)
477 char *buf;
479 buf = FormatTask(buffer, hdrstring, task, SysBase);
480 buf = NewRawDoFmt(errstring, RAWFMTFUNC_STRING, buf, alertNum) - 1;
481 buf = Alert_GetString(alertNum, buf);
482 *buf = 0;
483 D(bug("[FormatAlert] Header:\n%s\n", buffer));
485 /* For AT_CPU alerts NULL location is also valid */
486 if (location || (type == AT_CPU))
488 buf = FormatLocation(buf, locstring, location, SysBase);
490 D(bug("[FormatAlert] Location string:\n%s\n", buffer));
493 /* For AN_StackProbe limits information is useful */
494 if ((alertNum & ~AT_DeadEnd) == AN_StackProbe)
496 buf = NewRawDoFmt(stkstring, RAWFMTFUNC_STRING, buf, task->tc_SPLower, task->tc_SPUpper) - 1;
499 return buf;
502 STRPTR FormatTask(STRPTR buffer, const char *text, struct Task *task, struct ExecBase *SysBase)
504 STRPTR taskName;
506 if (Exec_CheckTask(task, SysBase))
507 taskName = task->tc_Node.ln_Name;
508 else
509 taskName = "-- task not found -- ";
511 return NewRawDoFmt(text, RAWFMTFUNC_STRING, buffer, task, taskName) - 1;
514 static const char modstring[] = "\nModule %s Segment %lu %s (0x%P) Offset 0x%P";
515 static const char funstring[] = "\nFunction %s (0x%P) Offset 0x%P";
517 STRPTR FormatLocation(STRPTR buf, const char *text, APTR location, struct ExecBase *SysBase)
519 char *modname, *segname, *symname;
520 void *segaddr, *symaddr;
521 unsigned int segnum;
523 buf = NewRawDoFmt(text, RAWFMTFUNC_STRING, buf, location) - 1;
525 if (DebugBase)
527 if (DecodeLocation(location,
528 DL_ModuleName , &modname, DL_SegmentNumber, &segnum ,
529 DL_SegmentName, &segname, DL_SegmentStart , &segaddr,
530 DL_SymbolName , &symname, DL_SymbolStart , &symaddr,
531 TAG_DONE))
533 if (!segname)
534 segname = "- unknown -";
536 buf = NewRawDoFmt(modstring, RAWFMTFUNC_STRING, buf, modname, segnum, segname, segaddr, location - segaddr) - 1;
538 if (symaddr)
540 if (!symname)
541 symname = "- unknown -";
543 buf = NewRawDoFmt(funstring, RAWFMTFUNC_STRING, buf, symname, symaddr, location - symaddr) - 1;
547 else if (KernelBase)
550 * If there's no debug.library yet, we likely crashed in boot code.
551 * In this case kickstart location information can be helpful.
552 * TODO: Perhaps we should get debug info and locate a module manually?
553 * It can be not that big code duplication, but will help if the crash
554 * happens not in the first module.
556 struct TagItem *tags = KrnGetBootInfo();
558 if (tags)
560 IPTR klow = LibGetTagData(KRN_KernelLowest, 0, tags);
561 IPTR kbase = LibGetTagData(KRN_KernelBase, 0, tags);
562 IPTR khi = LibGetTagData(KRN_KernelHighest, 0, tags);
564 buf = NewRawDoFmt("\nKickstart location: Lowest 0x%p, Base 0x%p, Highest 0x%p\n", RAWFMTFUNC_STRING, buf, klow, kbase, khi) - 1;
568 return buf;