2 Copyright © 1995-2012, 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>
17 #include <proto/kernel.h>
20 #include "exec_intern.h"
21 #include "exec_util.h"
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
))
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 " },
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 " },
91 { 0x43, "partition.library " },
93 /* This takes in 0x35 as well... */
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
[] =
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
)
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!";
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)
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 */
461 UBYTE subsys
= (alertnum
& 0x7f000000) >> 24;
463 buf
= Alert_AddString(buf
, getString(alertnum
, stringlist
[subsys
]));
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
)
479 buf
= FormatTask(buffer
, hdrstring
, task
, SysBase
);
480 buf
= NewRawDoFmt(errstring
, RAWFMTFUNC_STRING
, buf
, alertNum
) - 1;
481 buf
= Alert_GetString(alertNum
, buf
);
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;
502 STRPTR
FormatTask(STRPTR buffer
, const char *text
, struct Task
*task
, struct ExecBase
*SysBase
)
506 if (Exec_CheckTask(task
, SysBase
))
507 taskName
= task
->tc_Node
.ln_Name
;
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
;
523 buf
= NewRawDoFmt(text
, RAWFMTFUNC_STRING
, buf
, location
) - 1;
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
,
534 segname
= "- unknown -";
536 buf
= NewRawDoFmt(modstring
, RAWFMTFUNC_STRING
, buf
, modname
, segnum
, segname
, segaddr
, location
- segaddr
) - 1;
541 symname
= "- unknown -";
543 buf
= NewRawDoFmt(funstring
, RAWFMTFUNC_STRING
, buf
, symname
, symaddr
, location
- symaddr
) - 1;
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();
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;