revert between 56095 -> 55830 in arch
[AROS.git] / rom / exec / alertstrings.c
blobfeb7721f91554cf43d7ac9577a8b4b3ec5f970fb
1 /*
2 Copyright © 1995-2017, 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>
18 #include "etask.h"
19 #include "exec_intern.h"
20 #include "exec_util.h"
22 struct Errors
24 ULONG number;
25 STRPTR string;
28 /* Get a string from an array of type Errors. */
29 static STRPTR getString(ULONG alertnum, const struct Errors *errs)
31 /* Some of alert codes have AT_DeadEnd bit set, others have it reset.
32 However in real life AT_DeadEnd bit may be set for any error, so
33 we mask it out for comparison */
34 alertnum &= ~AT_DeadEnd;
36 while((errs->number) && ((errs->number & ~AT_DeadEnd) != alertnum))
38 errs++;
40 return errs->string;
43 static const struct Errors cpustrings[] =
45 { ACPU_BusErr, "Hardware bus fault/address error" },
46 { ACPU_AddressErr, "Illegal address access" },
47 { ACPU_InstErr, "Illegal instruction" },
48 { ACPU_DivZero, "Division by zero" },
49 { ACPU_CHK, "CHK instruction error" },
50 { ACPU_TRAPV, "TRAPV instruction error" },
51 { ACPU_PrivErr, "Privilege violation error" },
52 { ACPU_Trace, "Trace error" },
53 { ACPU_LineA, "Line 1010 (A) E mulator error" },
54 { ACPU_LineF, "Line 1111 (F) Emulator/Coprocessor error" },
55 { ACPU_Format, "Stack frame format error" },
56 { ACPU_Spurious, "Spurious interrupt error" },
57 { 0, "Unknown CPU error" }
60 static const struct Errors subsystems[] =
62 { 0x01, "exec.library " },
63 { 0x02, "graphics.library " },
64 { 0x03, "layers.library " },
65 { 0x04, "intuition.library " },
66 { 0x05, "math.library " },
67 { 0x07, "dos.library " },
68 { 0x08, "ramlib " },
69 { 0x09, "icon.library " },
70 { 0x0a, "expansion.library " },
71 { 0x0b, "diskfont.library " },
72 { 0x10, "audio.device " },
73 { 0x11, "console.device " },
74 { 0x12, "gameport.device " },
75 { 0x13, "keyboard.device " },
76 { 0x14, "trackdisk.device " },
77 { 0x15, "timer.device " },
78 { 0x20, "cia.resource " },
79 { 0x21, "disk.resource " },
80 { 0x22, "misc.resource " },
81 { 0x30, "bootstrap " },
82 { 0x31, "workbench " },
83 { 0x32, "diskcopy " },
84 { 0x33, "gadtools " },
85 { 0x34, "utility " },
87 { 0x40, "aros " },
88 { 0x41, "oop " },
89 { 0x42, "hidd " },
90 { 0x43, "partition.library " },
92 /* This takes in 0x35 as well... */
93 { 0x00, "unknown " }
96 static const struct Errors types[] =
98 { 0x01, "no memory for " },
99 { 0x02, "could not make library " },
100 { 0x03, "could not open library " },
101 { 0x04, "could not open device " },
102 { 0x05, "could not open resource " },
103 { 0x06, "IO error with " },
104 { 0x07, "no signal for/from " },
105 { 0x08, "bad parameter for/from " },
106 { 0x09, "close library error with " },
107 { 0x0a, "close device error with " },
108 { 0x0b, "process creating failure with " },
109 { 0x00, "unknown problem with "}
112 static const struct Errors execstrings[] =
114 { AN_ExcptVect, "MC68k Exception vector checksum" },
115 { AN_BaseChkSum, "ExecBase checksum" },
116 { AN_LibChkSum, "Library checksum failure" },
117 { AN_MemCorrupt, "Corrupt memory list detected" },
118 { AN_IntrMem, "No memory for interrupt servers" },
119 { AN_InitAPtr, "(obs) InitStruct of an APTR" },
120 { AN_SemCorrupt, "Semaphore in an illegal state" },
121 { AN_FreeTwice, "Memory freed twice" },
122 { AN_BogusExcpt, "Illegal mc68k exception taken" },
123 { AN_IOUsedTwice, "Attempt to reuse active IORequest" },
124 { AN_MemoryInsane, "Sanity check on memory list failed" },
125 { AN_IOAfterClose, "Attempt to use IORequest after close" },
126 { AN_StackProbe, "Stack extends out of range" },
127 { AN_BadFreeAddr, "Memory header not located" },
128 { AN_BadSemaphore, "Attempt to use the old message semaphore" },
129 { 0, "unknown exec.library error" }
132 static const struct Errors gfxstrings[] =
134 { AN_GfxNoMem, "Graphics out of memory" },
135 { AN_GfxNoMemMspc, "No memory to allocate MonitorSpec" },
136 { AN_LongFrame, "No memory for long frame" },
137 { AN_ShortFrame, "No memory for short frame" },
138 { AN_TextTmpRas, "Mo memory for TmpRas" },
139 { AN_BltBitMap, "No memory for BltBitMap" },
140 { AN_RegionMemory, "No memory for Region" },
141 { AN_MakeVPort, "No memory for MakeVPort" },
142 { AN_GfxNewError, "Error in GfxNew()" },
143 { AN_GfxFreeError, "Error in GfxFree()" },
144 { AN_GfxNoLCM, "Emergency memory not available" },
145 { AN_ObsoleteFont, "Unsupported font description used" },
146 { 0, "unknown graphics.library error" }
149 static const struct Errors unknownstrings[] =
151 { 0, "unknown error" }
154 static const struct Errors layersstrings[] =
156 { AN_LayersNoMem, "layers: no memory" },
157 { 0, "unknown layers.library error" }
160 static const struct Errors intuistrings[] =
162 { AN_GadgetType, "intuition: unknown gadget type" },
163 { AN_CreatePort, "intuition couldn't create port, no memory" },
164 { AN_ItemAlloc, "no memory for menu item" },
165 { AN_SubAlloc, "no memory for menu subitem" },
166 { AN_PlaneAlloc, "no memory for bitplane" },
167 { AN_ItemBoxTop, "top of item box < RelZero" },
168 { AN_OpenScreen, "no memory for OpenScreen()" },
169 { AN_OpenScrnRast, "no memory for OpenScreen() raster" },
170 { AN_SysScrnType, "unknown type of system screen" },
171 { AN_AddSWGadget, "add SW gadgets, no memory" },
172 { AN_OpenWindow, "no memory for OpenWindow()" },
173 { AN_BadState, "bad state return entering intuition" },
174 { AN_BadMessage, "bad message received by IDCMP" },
175 { AN_WeirdEcho, "weird echo causing incomprehension" },
176 { AN_NoConsole, "couldn't open the console.device" },
177 { AN_NoISem, "intuition skipped obtaining a semaphore" },
178 { AN_ISemOrder, "intuition got a semaphore in wrong order" },
179 { 0, "unknown intuition.library error" }
182 static const struct Errors mathstrings[] =
184 { 0, "unknown math library error" }
187 static const struct Errors dosstrings[] =
189 { AN_StartMem, "no memory at startup" },
190 { AN_EndTask, "EndTask did not end task" },
191 { AN_QPktFail, "QPkt failure" },
192 { AN_AsyncPkt, "unexpected DOS packet received" },
193 { AN_FreeVec, "freevec failed" },
194 { AN_DiskBlkSeq, "disk block sequence error" },
195 { AN_BitMap, "disk bitmap corrupt" },
196 { AN_KeyFree, "disk key already free" },
197 { AN_BadChkSum, "disk checksum bad" },
198 { AN_DiskError, "disk error" },
199 { AN_KeyRange, "disk key out of range" },
200 { AN_BadOverlay, "bad overlay" },
201 { AN_BadInitFunc, "invalid initialization packet for cli/shell" },
202 { AN_FileReclosed, "filehandle closed more than once" },
203 { 0, "unknown dos.library error" }
206 static const struct Errors ramlibstrings[] =
208 { AN_BadSegList, "bad library seglist" },
209 { 0, "unknown ramlib/lddemon error" }
212 static const struct Errors iconstrings[] =
214 { 0, "unknown icon.library error" }
217 static const struct Errors expanstrings[] =
219 { AN_BadExpansionFree, "expansion freeing region already freed"},
220 { 0, "unknown expansion.library error" }
223 static const struct Errors utilitystrings[] =
225 {0, "unknown utility.library error" }
228 static const struct Errors keymapstrings[] =
230 {0, "unknown keymap error" }
233 static const struct Errors dfontstrings[] =
235 { 0, "unknown diskfont.library error" }
238 static const struct Errors audiostrings[] =
240 { 0, "unknown audio.device error" }
243 static const struct Errors consolestrings[] =
245 { AN_NoWindow, "can't open initial console window" },
246 { 0, "unknown console.device error" }
249 static const struct Errors gameportstrings[] =
251 { 0, "unknown gameport.device error" }
254 static const struct Errors keyboardstrings[] =
256 { 0, "unknown keyboard.device error" }
259 static const struct Errors trackdiskstrings[] =
261 { AN_TDCalibSeek, "trackdisk calibrate seek error" },
262 { 0, "unknown trackdisk.device error" }
265 static const struct Errors timerstrings[] =
267 { AN_TMBadReq, "bad timer request" },
268 { AN_TMBadSupply, "bad timer powersupply frequency" },
269 { 0, "unknown timer.device error" }
272 static const struct Errors ciastrings[] =
274 { 0, "unknown cia resource error" }
277 static const struct Errors diskstrings[] =
279 { AN_DRHasDisk, "get disk unit, already has disk" },
280 { AN_DRIntNoAct,"disk interrupt, no active unit" },
281 { 0, "unknown disk.resource error" }
284 static const struct Errors miscstrings[] =
286 { 0, "unknown misc.resource error" }
289 static const struct Errors bootstrings[] =
291 { AN_BootError, "boot code returned an error" },
292 { 0, "unknown bootstrap error" }
295 static const struct Errors workbenchstrings[] =
297 { AN_NoFonts, "no fonts for workbench" },
298 { AN_WBBadStartupMsg1, "bad startup message 1 for workbench" },
299 { AN_WBBadStartupMsg2, "bad startup message 2 for workbench" },
300 { AN_WBBadIOMsg, "bad IO message for workbench" },
301 { AN_WBReLayoutToolMenu, "error with layout on tools menu" },
302 { 0, "unknown workbench error" }
305 static const struct Errors diskcopystrings[] =
307 {0, "unknown diskcopy error" }
310 static const struct Errors gadtoolsstrings[] =
312 {0, "unknown gadtools.library error" }
315 static const struct Errors arosstrings[] =
317 {0, "unknown aros.library error" }
320 static const struct Errors oopstrings[] =
322 {0, "unknown oop.library error" }
325 static const struct Errors hiddstrings[] =
327 {0, "unknown Hidd system error" }
330 static const struct Errors partitionstrings[] =
332 {0, "unknown partition.library error" }
335 static const struct Errors *const stringlist[] =
337 /* 0x00 */
338 unknownstrings,
339 execstrings,
340 gfxstrings,
341 layersstrings,
342 intuistrings,
343 mathstrings,
344 unknownstrings,
345 dosstrings,
346 ramlibstrings,
347 iconstrings,
348 expanstrings,
349 dfontstrings,
350 utilitystrings,
351 keymapstrings,
352 unknownstrings,
353 unknownstrings,
355 /* 0x10 */
356 audiostrings,
357 consolestrings,
358 gameportstrings,
359 keyboardstrings,
360 trackdiskstrings,
361 timerstrings,
362 unknownstrings,
363 unknownstrings,
364 unknownstrings,
365 unknownstrings,
366 unknownstrings,
367 unknownstrings,
368 unknownstrings,
369 unknownstrings,
370 unknownstrings,
371 unknownstrings,
373 /* 0x20 */
374 ciastrings,
375 diskstrings,
376 miscstrings,
377 unknownstrings,
378 unknownstrings,
379 unknownstrings,
380 unknownstrings,
381 unknownstrings,
382 unknownstrings,
383 unknownstrings,
384 unknownstrings,
385 unknownstrings,
386 unknownstrings,
387 unknownstrings,
388 unknownstrings,
389 unknownstrings,
391 /* 0x30 */
392 bootstrings,
393 workbenchstrings,
394 diskcopystrings,
395 gadtoolsstrings,
396 unknownstrings,
397 unknownstrings,
398 unknownstrings,
399 unknownstrings,
400 unknownstrings,
401 unknownstrings,
402 unknownstrings,
403 unknownstrings,
404 unknownstrings,
405 unknownstrings,
406 unknownstrings,
407 unknownstrings,
409 /* 0x40 */
410 arosstrings,
411 oopstrings,
412 hiddstrings,
413 partitionstrings
416 /* Similar to strcpy() but returns a pointer to the next byte beyond the
417 copied string. Useful for concatenation. */
418 STRPTR Alert_AddString(STRPTR dest, CONST_STRPTR src)
420 while(*src)
422 *dest++ = *src++;
424 return dest;
427 STRPTR Alert_GetTitle(ULONG alertNum)
429 if((alertNum & 0x00ff0000) == AG_NoMemory)
430 return "Not Enough Memory!";
431 else if(alertNum & AT_DeadEnd)
432 return "Software Failure!";
433 else
434 return "Recoverable Alert!";
437 /* Decode the alert number, and try and work out what string to get */
438 STRPTR Alert_GetString(ULONG alertnum, STRPTR buf)
440 /* Is this a CPU alert? */
441 if((alertnum & 0x7f008000) == 0)
443 /* Yes */
444 buf = Alert_AddString(buf, getString(alertnum, cpustrings));
446 /* Is this a General alert */
447 else if((alertnum & 0x8000) == 0x8000)
449 UBYTE type = (alertnum & 0x00FF0000) >> 16;
450 UWORD obj = (alertnum & 0x7fff);
451 UBYTE subsys = (alertnum & 0x7f000000) >> 24;
453 buf = Alert_AddString(buf, getString(obj, subsystems));
454 buf = Alert_AddString(buf, getString(type, types));
455 buf = Alert_AddString(buf, getString(subsys, subsystems));
457 /* This must be a specific alert */
458 else
460 UBYTE subsys = (alertnum & 0x7f000000) >> 24;
462 buf = Alert_AddString(buf, getString(alertnum, stringlist[subsys]));
465 *buf = 0;
466 return buf;
469 static const char hdrstring[] = "Task : 0x%P - %s";
470 static const char errstring[] = "\nError: 0x%08lx - ";
471 static const char locstring[] = "\nPC : 0x%P";
472 static const char stkstring[] = "\nStack: 0x%P - 0x%P";
474 STRPTR FormatAlert(char *buffer, ULONG alertNum, struct Task *task, APTR location, UBYTE type, struct ExecBase *SysBase)
476 char *buf;
478 buf = FormatTask(buffer, hdrstring, task, SysBase);
479 buf = NewRawDoFmt(errstring, RAWFMTFUNC_STRING, buf, alertNum) - 1;
480 buf = Alert_GetString(alertNum, buf);
481 *buf = 0;
482 D(bug("[FormatAlert] Header:\n%s\n", buffer));
484 /* For AT_CPU alerts NULL location is also valid */
485 if (location || (type == AT_CPU))
487 buf = FormatLocation(buf, locstring, location, SysBase);
489 D(bug("[FormatAlert] Location string:\n%s\n", buffer));
492 /* For AN_StackProbe limits information is useful */
493 if ((alertNum & ~AT_DeadEnd) == AN_StackProbe)
495 buf = NewRawDoFmt(stkstring, RAWFMTFUNC_STRING, buf, task->tc_SPLower, task->tc_SPUpper) - 1;
498 return buf;
501 STRPTR FormatTask(STRPTR buffer, const char *text, struct Task *task, struct ExecBase *SysBase)
503 STRPTR taskName;
505 if (Exec_CheckTask(task, SysBase))
506 taskName = task->tc_Node.ln_Name;
507 else
508 taskName = "-- task not found -- ";
510 return NewRawDoFmt(text, RAWFMTFUNC_STRING, buffer, task, taskName) - 1;
513 static const char modstring[] = "\nModule %s Segment %lu %s (0x%P) Offset 0x%P";
514 static const char funstring[] = "\nFunction %s (0x%P) Offset 0x%P";
516 STRPTR FormatLocation(STRPTR buf, const char *text, APTR location, struct ExecBase *SysBase)
518 char *modname, *segname, *symname;
519 void *segaddr, *symaddr;
520 unsigned int segnum;
522 buf = NewRawDoFmt(text, RAWFMTFUNC_STRING, buf, location) - 1;
524 if (DebugBase)
526 if (DecodeLocation(location,
527 DL_ModuleName , &modname, DL_SegmentNumber, &segnum ,
528 DL_SegmentName, &segname, DL_SegmentStart , &segaddr,
529 DL_SymbolName , &symname, DL_SymbolStart , &symaddr,
530 TAG_DONE))
532 if (!segname)
533 segname = "- unknown -";
535 buf = NewRawDoFmt(modstring, RAWFMTFUNC_STRING, buf, modname, segnum, segname, segaddr, location - segaddr) - 1;
537 if (symaddr)
539 if (!symname)
540 symname = "- unknown -";
542 buf = NewRawDoFmt(funstring, RAWFMTFUNC_STRING, buf, symname, symaddr, location - symaddr) - 1;
546 else if (KernelBase)
549 * If there's no debug.library yet, we likely crashed in boot code.
550 * In this case kickstart location information can be helpful.
551 * TODO: Perhaps we should get debug info and locate a module manually?
552 * It can be not that big code duplication, but will help if the crash
553 * happens not in the first module.
555 struct TagItem *tags = KrnGetBootInfo();
557 if (tags)
559 IPTR klow = LibGetTagData(KRN_KernelLowest, 0, tags);
560 IPTR kbase = LibGetTagData(KRN_KernelBase, 0, tags);
561 IPTR khi = LibGetTagData(KRN_KernelHighest, 0, tags);
563 buf = NewRawDoFmt("\nKickstart location: Lowest 0x%p, Base 0x%p, Highest 0x%p\n", RAWFMTFUNC_STRING, buf, klow, kbase, khi) - 1;
567 return buf;