2 * A library of alert strings and useful functions.
3 * Used by platform-specific Alert() implementations
6 #include <aros/debug.h>
7 #include <exec/alerts.h>
8 #include <exec/rawfmt.h>
9 #include <exec/tasks.h>
10 #include <libraries/debug.h>
11 #include <proto/debug.h>
12 #include <proto/kernel.h>
15 #include "exec_intern.h"
16 #include "exec_util.h"
24 /* Get a string from an array of type Errors. */
25 static STRPTR
getString(ULONG alertnum
, const struct Errors
*errs
)
27 /* Some of alert codes have AT_DeadEnd bit set, others have it reset.
28 However in real life AT_DeadEnd bit may be set for any error, so
29 we mask it out for comparison */
30 alertnum
&= ~AT_DeadEnd
;
32 while((errs
->number
) && ((errs
->number
& ~AT_DeadEnd
) != alertnum
))
39 static const struct Errors cpustrings
[] =
41 { ACPU_BusErr
, "Hardware bus fault/address error" },
42 { ACPU_AddressErr
, "Illegal address access" },
43 { ACPU_InstErr
, "Illegal instruction" },
44 { ACPU_DivZero
, "Division by zero" },
45 { ACPU_CHK
, "CHK instruction error" },
46 { ACPU_TRAPV
, "TRAPV instruction error" },
47 { ACPU_PrivErr
, "Priviledge violation error" },
48 { ACPU_Trace
, "Trace error" },
49 { ACPU_LineA
, "Line 1010 (A) E mulator error" },
50 { ACPU_LineF
, "Line 1111 (F) Emulator/Coprocessor error" },
51 { ACPU_Format
, "Stack frame format error" },
52 { ACPU_Spurious
, "Spurious interrupt error" },
53 { 0, "Unknown CPU error" }
56 static const struct Errors subsystems
[] =
58 { 0x01, "exec.library " },
59 { 0x02, "graphics.library " },
60 { 0x03, "layers.library " },
61 { 0x04, "intuition.library " },
62 { 0x05, "math.library " },
63 { 0x07, "dos.library " },
65 { 0x09, "icon.library " },
66 { 0x0a, "expansion.library " },
67 { 0x0b, "diskfont.library " },
68 { 0x10, "audio.device " },
69 { 0x11, "console.device " },
70 { 0x12, "gameport.device " },
71 { 0x13, "keyboard.device " },
72 { 0x14, "trackdisk.device " },
73 { 0x15, "timer.device " },
74 { 0x20, "cia.resource " },
75 { 0x21, "disk.resource " },
76 { 0x22, "misc.resource " },
77 { 0x30, "bootstrap " },
78 { 0x31, "workbench " },
79 { 0x32, "diskcopy " },
80 { 0x33, "gadtools " },
87 /* This takes in 0x35 as well... */
91 static const struct Errors types
[] =
93 { 0x01, "no memory for " },
94 { 0x02, "could not make library " },
95 { 0x03, "could not open library " },
96 { 0x04, "could not open device " },
97 { 0x05, "could not open resource " },
98 { 0x06, "IO error with " },
99 { 0x07, "no signal for/from " },
100 { 0x08, "bad parameter for/from " },
101 { 0x09, "close library error with " },
102 { 0x0a, "close device error with " },
103 { 0x0b, "process creating failure with " },
104 { 0x00, "unknown problem with "}
107 static const struct Errors execstrings
[] =
109 { AN_ExcptVect
, "MC68k Exception vector checksum" },
110 { AN_BaseChkSum
, "ExecBase checksum" },
111 { AN_LibChkSum
, "Library checksum failure" },
112 { AN_MemCorrupt
, "Corrupt memory list detected" },
113 { AN_IntrMem
, "No memory for interrupt servers" },
114 { AN_InitAPtr
, "(obs) InitStruct of an APTR" },
115 { AN_SemCorrupt
, "Semaphore in an illegal state" },
116 { AN_FreeTwice
, "Memory freed twice" },
117 { AN_BogusExcpt
, "Illegal mc68k exception taken" },
118 { AN_IOUsedTwice
, "Attempt to reuse active IORequest" },
119 { AN_MemoryInsane
, "Sanity check on memory list failed" },
120 { AN_IOAfterClose
, "Attempt to use IORequest after close" },
121 { AN_StackProbe
, "Stack extends out of range" },
122 { AN_BadFreeAddr
, "Memory header not located" },
123 { AN_BadSemaphore
, "Attempt to use the old message semaphore" },
124 { 0, "unknown exec.library error" }
127 static const struct Errors gfxstrings
[] =
129 { AN_GfxNoMem
, "Graphics out of memory" },
130 { AN_GfxNoMemMspc
, "No memory to allocate MonitorSpec" },
131 { AN_LongFrame
, "No memory for long frame" },
132 { AN_ShortFrame
, "No memory for short frame" },
133 { AN_TextTmpRas
, "Mo memory for TmpRas" },
134 { AN_BltBitMap
, "No memory for BltBitMap" },
135 { AN_RegionMemory
, "No memory for Region" },
136 { AN_MakeVPort
, "No memory for MakeVPort" },
137 { AN_GfxNewError
, "Error in GfxNew()" },
138 { AN_GfxFreeError
, "Error in GfxFree()" },
139 { AN_GfxNoLCM
, "Emergency memory not available" },
140 { AN_ObsoleteFont
, "Unsupported font description used" },
141 { 0, "unknown graphics.library error" }
144 static const struct Errors unknownstrings
[] =
146 { 0, "unknown error" }
149 static const struct Errors layersstrings
[] =
151 { AN_LayersNoMem
, "layers: no memory" },
152 { 0, "unknown layers.library error" }
155 static const struct Errors intuistrings
[] =
157 { AN_GadgetType
, "intuition: unknown gadget type" },
158 { AN_CreatePort
, "intuition couldn't create port, no memory" },
159 { AN_ItemAlloc
, "no memory for menu item" },
160 { AN_SubAlloc
, "no memory for menu subitem" },
161 { AN_PlaneAlloc
, "no memory for bitplane" },
162 { AN_ItemBoxTop
, "top of item box < RelZero" },
163 { AN_OpenScreen
, "no memory for OpenScreen()" },
164 { AN_OpenScrnRast
, "no memory for OpenScreen() raster" },
165 { AN_SysScrnType
, "unknown type of system screen" },
166 { AN_AddSWGadget
, "add SW gadgets, no memory" },
167 { AN_OpenWindow
, "no memory for OpenWindow()" },
168 { AN_BadState
, "bad state return entering intuition" },
169 { AN_BadMessage
, "bad message received by IDCMP" },
170 { AN_WeirdEcho
, "weird echo causing incomprehension" },
171 { AN_NoConsole
, "couldn't open the console.device" },
172 { AN_NoISem
, "intuition skipped obtaining a semaphore" },
173 { AN_ISemOrder
, "intuition got a semaphore in wrong order" },
174 { 0, "unknown intuition.library error" }
177 static const struct Errors mathstrings
[] =
179 { 0, "unknown math library error" }
182 static const struct Errors dosstrings
[] =
184 { AN_StartMem
, "no memory at startup" },
185 { AN_EndTask
, "EndTask did not end task" },
186 { AN_QPktFail
, "QPkt failure" },
187 { AN_AsyncPkt
, "unexpected DOS packet received" },
188 { AN_FreeVec
, "freevec failed" },
189 { AN_DiskBlkSeq
, "disk block sequence error" },
190 { AN_BitMap
, "disk bitmap corrupt" },
191 { AN_KeyFree
, "disk key already free" },
192 { AN_BadChkSum
, "disk checksum bad" },
193 { AN_DiskError
, "disk error" },
194 { AN_KeyRange
, "disk key out of range" },
195 { AN_BadOverlay
, "bad overlay" },
196 { AN_BadInitFunc
, "invalid initialization packet for cli/shell" },
197 { AN_FileReclosed
, "filehandle closed more than once" },
198 { 0, "unknown dos.library error" }
201 static const struct Errors ramlibstrings
[] =
203 { AN_BadSegList
, "bad library seglist" },
204 { 0, "unknown ramlib/lddemon error" }
207 static const struct Errors iconstrings
[] =
209 { 0, "unknown icon.library error" }
212 static const struct Errors expanstrings
[] =
214 { AN_BadExpansionFree
, "expansion freeing region already freed"},
215 { 0, "unknown expansion.library error" }
218 static const struct Errors utilitystrings
[] =
220 {0, "unknown utility.library error" }
223 static const struct Errors keymapstrings
[] =
225 {0, "unknown keymap error" }
228 static const struct Errors dfontstrings
[] =
230 { 0, "unknown diskfont.library error" }
233 static const struct Errors audiostrings
[] =
235 { 0, "unknown audio.device error" }
238 static const struct Errors consolestrings
[] =
240 { AN_NoWindow
, "can't open initial console window" },
241 { 0, "unknown console.device error" }
244 static const struct Errors gameportstrings
[] =
246 { 0, "unknown gameport.device error" }
249 static const struct Errors keyboardstrings
[] =
251 { 0, "unknown keyboard.device error" }
254 static const struct Errors trackdiskstrings
[] =
256 { AN_TDCalibSeek
, "trackdisk calibrate seek error" },
257 { 0, "unknown trackdisk.device error" }
260 static const struct Errors timerstrings
[] =
262 { AN_TMBadReq
, "bad timer request" },
263 { AN_TMBadSupply
, "bad timer powersupply frequency" },
264 { 0, "unknown timer.device error" }
267 static const struct Errors ciastrings
[] =
269 { 0, "unknown cia resource error" }
272 static const struct Errors diskstrings
[] =
274 { AN_DRHasDisk
, "get disk unit, already has disk" },
275 { AN_DRIntNoAct
,"disk interrupt, no active unit" },
276 { 0, "unknown disk.resource error" }
279 static const struct Errors miscstrings
[] =
281 { 0, "unknown misc.resource error" }
284 static const struct Errors bootstrings
[] =
286 { AN_BootError
, "boot code returned an error" },
287 { 0, "unknown bootstrap error" }
290 static const struct Errors workbenchstrings
[] =
292 { AN_NoFonts
, "no fonts for workbench" },
293 { AN_WBBadStartupMsg1
, "bad startup message 1 for workbench" },
294 { AN_WBBadStartupMsg2
, "bad startup message 2 for workbench" },
295 { AN_WBBadIOMsg
, "bad IO message for workbench" },
296 { AN_WBReLayoutToolMenu
, "error with layout on tools menu" },
297 { 0, "unknown workbench error" }
300 static const struct Errors diskcopystrings
[] =
302 {0, "unknown diskcopy error" }
305 static const struct Errors gadtoolsstrings
[] =
307 {0, "unknown gadtools.library error" }
310 static const struct Errors arosstrings
[] =
312 {0, "unknown aros.library error" }
315 static const struct Errors oopstrings
[] =
317 {0, "unknown oop.library error" }
320 static const struct Errors hiddstrings
[] =
322 {0, "unknown Hidd system error" }
325 static const struct Errors
*const stringlist
[] =
405 /* Similar to strcpy() but returns a pointer to the next byte beyond the
406 copied string. Useful for concatenation. */
407 STRPTR
Alert_AddString(STRPTR dest
, CONST_STRPTR src
)
416 STRPTR
Alert_GetTitle(ULONG alertNum
)
418 if(alertNum
& AG_NoMemory
)
419 return "Not Enough Memory!";
420 else if(alertNum
& AT_DeadEnd
)
421 return "Software Failure!";
423 return "Recoverable Alert!";
426 /* Decode the alert number, and try and work out what string to get */
427 STRPTR
Alert_GetString(ULONG alertnum
, STRPTR buf
)
429 /* Is this a CPU alert? */
430 if((alertnum
& 0x7f008000) == 0)
433 buf
= Alert_AddString(buf
, getString(alertnum
, cpustrings
));
435 /* Is this a General alert */
436 else if((alertnum
& 0x8000) == 0x8000)
438 UBYTE type
= (alertnum
& 0x00FF0000) >> 16;
439 UWORD obj
= (alertnum
& 0x7fff);
440 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
442 buf
= Alert_AddString(buf
, getString(obj
, subsystems
));
443 buf
= Alert_AddString(buf
, getString(type
, types
));
444 buf
= Alert_AddString(buf
, getString(subsys
, subsystems
));
446 /* This must be a specific alert */
449 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
452 buf
= Alert_AddString(buf
, getString(alertnum
, stringlist
[subsys
]));
454 buf
= Alert_AddString(buf
, "unknown error");
461 static const char hdrstring
[] = "Task : 0x%P - %s";
462 static const char errstring
[] = "\nError: 0x%08lx - ";
463 static const char locstring
[] = "\nPC : 0x%P";
464 static const char stkstring
[] = "\nStack: 0x%P - 0x%P";
466 STRPTR
FormatAlert(char *buffer
, ULONG alertNum
, struct Task
*task
, APTR location
, UBYTE type
, struct ExecBase
*SysBase
)
470 buf
= FormatTask(buffer
, hdrstring
, task
, SysBase
);
471 buf
= NewRawDoFmt(errstring
, RAWFMTFUNC_STRING
, buf
, alertNum
) - 1;
472 buf
= Alert_GetString(alertNum
, buf
);
474 D(bug("[FormatAlert] Header:\n%s\n", buffer
));
476 /* For AT_CPU alerts NULL location is also valid */
477 if (location
|| (type
== AT_CPU
))
479 buf
= FormatLocation(buf
, locstring
, location
, SysBase
);
481 D(bug("[FormatAlert] Location string:\n%s\n", buffer
));
484 /* For AN_StackProbe limits information is useful */
485 if ((alertNum
& ~AT_DeadEnd
) == AN_StackProbe
)
487 buf
= NewRawDoFmt(stkstring
, RAWFMTFUNC_STRING
, buf
, task
->tc_SPLower
, task
->tc_SPUpper
) - 1;
493 STRPTR
FormatTask(STRPTR buffer
, const char *text
, struct Task
*task
, struct ExecBase
*SysBase
)
497 if (Exec_CheckTask(task
, SysBase
))
498 taskName
= task
->tc_Node
.ln_Name
;
500 taskName
= "-- task not found -- ";
502 return NewRawDoFmt(text
, RAWFMTFUNC_STRING
, buffer
, task
, taskName
) - 1;
505 static const char modstring
[] = "\nModule %s Segment %lu %s (0x%P) Offset 0x%P";
506 static const char funstring
[] = "\nFunction %s (0x%P) Offset 0x%P";
508 STRPTR
FormatLocation(STRPTR buf
, const char *text
, APTR location
, struct ExecBase
*SysBase
)
510 char *modname
, *segname
, *symname
;
511 void *segaddr
, *symaddr
;
514 buf
= NewRawDoFmt(text
, RAWFMTFUNC_STRING
, buf
, location
) - 1;
518 if (DecodeLocation(location
,
519 DL_ModuleName
, &modname
, DL_SegmentNumber
, &segnum
,
520 DL_SegmentName
, &segname
, DL_SegmentStart
, &segaddr
,
521 DL_SymbolName
, &symname
, DL_SymbolStart
, &symaddr
,
525 segname
= "- unknown -";
527 buf
= NewRawDoFmt(modstring
, RAWFMTFUNC_STRING
, buf
, modname
, segnum
, segname
, segaddr
, location
- segaddr
) - 1;
532 symname
= "- unknown -";
534 buf
= NewRawDoFmt(funstring
, RAWFMTFUNC_STRING
, buf
, symname
, symaddr
, location
- symaddr
) - 1;
541 * If there's no debug.library yet, we likely crashed in boot code.
542 * In this case kickstart location information can be helpful.
543 * TODO: Perhaps we should get debug info and locate a module manually?
544 * It can be not that big code duplication, but will help if the crash
545 * happens not in the first module.
547 struct TagItem
*tags
= KrnGetBootInfo();
551 IPTR klow
= LibGetTagData(KRN_KernelLowest
, 0, tags
);
552 IPTR kbase
= LibGetTagData(KRN_KernelBase
, 0, tags
);
553 IPTR khi
= LibGetTagData(KRN_KernelHighest
, 0, tags
);
555 buf
= NewRawDoFmt("\nKickstart location: Lowest 0x%p, Base 0x%p, Highest 0x%p\n", RAWFMTFUNC_STRING
, buf
, klow
, kbase
, khi
) - 1;