2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
7 * A library of alert strings and useful functions.
8 * Used by platform-specific Alert() implementations
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>
19 #include "exec_intern.h"
20 #include "exec_util.h"
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
))
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 " },
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 " },
90 { 0x43, "partition.library " },
92 /* This takes in 0x35 as well... */
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
[] =
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
)
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!";
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)
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 */
460 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
462 buf
= Alert_AddString(buf
, getString(alertnum
, stringlist
[subsys
]));
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
)
478 buf
= FormatTask(buffer
, hdrstring
, task
, SysBase
);
479 buf
= NewRawDoFmt(errstring
, RAWFMTFUNC_STRING
, buf
, alertNum
) - 1;
480 buf
= Alert_GetString(alertNum
, buf
);
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;
501 STRPTR
FormatTask(STRPTR buffer
, const char *text
, struct Task
*task
, struct ExecBase
*SysBase
)
505 if (Exec_CheckTask(task
, SysBase
))
506 taskName
= task
->tc_Node
.ln_Name
;
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
;
522 buf
= NewRawDoFmt(text
, RAWFMTFUNC_STRING
, buf
, location
) - 1;
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
,
533 segname
= "- unknown -";
535 buf
= NewRawDoFmt(modstring
, RAWFMTFUNC_STRING
, buf
, modname
, segnum
, segname
, segaddr
, location
- segaddr
) - 1;
540 symname
= "- unknown -";
542 buf
= NewRawDoFmt(funstring
, RAWFMTFUNC_STRING
, buf
, symname
, symaddr
, location
- symaddr
) - 1;
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();
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;