Do not try to get stack pointer from invalid ESP field, which coincidentally
[AROS.git] / rom / exec / alert.c
blob7a2080b44aacc369cd34212f72e0ff0385c299cd
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Display an alert.
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <exec/alerts.h>
11 #include <exec/execbase.h>
12 #include <exec/rawfmt.h>
13 #include <proto/exec.h>
14 #include <proto/kernel.h>
15 #include <string.h>
17 #include "exec_intern.h"
18 #include "exec_util.h"
19 #include "etask.h"
21 /* x86/64 kernel.resource doesn't have KrnIsSuper() */
22 #ifndef KrnIsSuper
23 #define KrnIsSuper() 0
24 #endif
26 /*****************************************************************************
28 NAME */
30 AROS_LH1(void, Alert,
32 /* SYNOPSIS */
33 AROS_LHA(ULONG, alertNum, D7),
35 /* LOCATION */
36 struct ExecBase *, SysBase, 18, Exec)
38 /* FUNCTION
39 Alerts the user of a serious system problem.
41 INPUTS
42 alertNum - This is a number which contains information about
43 the reason for the call.
45 RESULT
46 This routine may return, if the alert is not a dead-end one.
48 NOTES
49 You should not call this routine because it halts the machine,
50 displays the message and then may reboot it.
52 EXAMPLE
53 // Dead-End alert: 680x0 Access To Odd Address
54 Alert (0x80000003);
56 BUGS
58 SEE ALSO
60 INTERNALS
62 ******************************************************************************/
64 AROS_LIBFUNC_INIT
66 struct Task *task = SysBase->ThisTask;
67 struct IntETask *iet = NULL;
68 int supervisor = KrnIsSuper();
70 D(bug("[exec] Alert 0x%08X\n", alertNum));
72 if (task)
74 iet = GetIntETask(task);
76 /* Do we already have location set? */
77 if (!(iet->iet_AlertFlags & AF_Location))
79 /* If no, the location is where we were called from */
80 iet->iet_AlertFlags |= AF_Location;
82 if (supervisor && ((alertNum & ~AT_DeadEnd) == AN_StackProbe))
85 * Special case: AN_StackProbe issued by kernel's task dispatcher.
86 * Pick up data from task's context.
88 struct ExceptionContext *ctx = iet->iet_Context;
90 iet->iet_AlertLocation = (APTR)ctx->PC;
91 iet->iet_AlertStack = (APTR)ctx->FP;
93 else
95 iet->iet_AlertLocation = __builtin_return_address(0);
97 * And backtrace starts at caller's frame.
98 * On ARM we don't have frame pointer so we can't do backtrace.
99 * __builtin_frame_address(1) will return garbage, so don't do this.
101 #ifdef __arm__
102 iet->iet_AlertStack = NULL;
103 #else
104 iet->iet_AlertStack = __builtin_frame_address(1);
105 #endif
106 D(bug("[Alert] Previous frame 0x%p, caller 0x%p\n", iet->iet_AlertStack, iet->iet_AlertLocation));
112 * If we are running in user mode we should first try to report a problem
113 * using Intuition display.
115 if (!supervisor)
117 alertNum = Exec_UserAlert(alertNum, SysBase);
118 if (!alertNum)
119 return;
123 * We're here if Intuition failed. Use safe (but not so
124 * system and user-friendly) way to post alerts.
126 Disable();
127 Exec_SystemAlert(alertNum, SysBase);
128 Enable();
131 * We succesfully displayed an alert in supervisor mode.
132 * Clear alert status by clearing respective fields in ETask.
134 if (iet)
136 ResetETask(iet);
139 if (alertNum & AT_DeadEnd)
141 /* Um, we have to do something here in order to prevent the
142 computer from continuing... */
143 ColdReboot();
144 ShutdownA(SD_ACTION_COLDREBOOT);
147 AROS_LIBFUNC_EXIT