Revert 45697:
[reactos.git] / lib / rtl / exception.c
1 /* COPYRIGHT: See COPYING in the top level directory
2 * PROJECT: ReactOS Runtime Library
3 * PURPOSE: User-Mode Exception Support
4 * FILE: lib/rtl/exception.c
5 * PROGRAMERS: Alex Ionescu (alex@relsoft.net)
6 * David Welch <welch@cwcom.net>
7 * Skywing <skywing@valhallalegends.com>
8 * KJK::Hyperion <noog@libero.it>
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <rtl.h>
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* FUNCTIONS ***************************************************************/
19
20 #if !defined(_M_IX86) && !defined(_M_AMD64)
21
22 /*
23 * @implemented
24 */
25 VOID
26 NTAPI
27 RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord)
28 {
29 CONTEXT Context;
30 NTSTATUS Status;
31
32 /* Capture the context */
33 RtlCaptureContext(&Context);
34
35 /* Save the exception address */
36 ExceptionRecord->ExceptionAddress = _ReturnAddress();
37
38 /* Write the context flag */
39 Context.ContextFlags = CONTEXT_FULL;
40
41 /* Check if user mode debugger is active */
42 if (RtlpCheckForActiveDebugger())
43 {
44 /* Raise an exception immediately */
45 Status = ZwRaiseException(ExceptionRecord, &Context, TRUE);
46 }
47 else
48 {
49 /* Dispatch the exception and check if we should continue */
50 if (!RtlDispatchException(ExceptionRecord, &Context))
51 {
52 /* Raise the exception */
53 Status = ZwRaiseException(ExceptionRecord, &Context, FALSE);
54 }
55 else
56 {
57 /* Continue, go back to previous context */
58 Status = ZwContinue(&Context, FALSE);
59 }
60 }
61
62 /* If we returned, raise a status */
63 RtlRaiseStatus(Status);
64 }
65
66 #endif
67
68 #if !defined(_M_IX86)
69
70 #ifdef _MSC_VER
71 #pragma warning(push)
72 #pragma warning(disable:4717) // RtlRaiseStatus is recursive by design
73 #endif
74
75 /*
76 * @implemented
77 */
78 VOID
79 NTAPI
80 RtlRaiseStatus(IN NTSTATUS Status)
81 {
82 EXCEPTION_RECORD ExceptionRecord;
83 CONTEXT Context;
84
85 /* Capture the context */
86 RtlCaptureContext(&Context);
87
88 /* Create an exception record */
89 ExceptionRecord.ExceptionAddress = _ReturnAddress();
90 ExceptionRecord.ExceptionCode = Status;
91 ExceptionRecord.ExceptionRecord = NULL;
92 ExceptionRecord.NumberParameters = 0;
93 ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
94
95 /* Write the context flag */
96 Context.ContextFlags = CONTEXT_FULL;
97
98 /* Check if user mode debugger is active */
99 if (RtlpCheckForActiveDebugger())
100 {
101 /* Raise an exception immediately */
102 ZwRaiseException(&ExceptionRecord, &Context, TRUE);
103 }
104 else
105 {
106 /* Dispatch the exception */
107 RtlDispatchException(&ExceptionRecord, &Context);
108
109 /* Raise exception if we got here */
110 Status = ZwRaiseException(&ExceptionRecord, &Context, FALSE);
111 }
112
113 /* If we returned, raise a status */
114 RtlRaiseStatus(Status);
115 }
116
117 #ifdef _MSC_VER
118 #pragma warning(pop)
119 #endif
120
121 #endif
122
123 /*
124 * @implemented
125 */
126 USHORT
127 NTAPI
128 RtlCaptureStackBackTrace(IN ULONG FramesToSkip,
129 IN ULONG FramesToCapture,
130 OUT PVOID *BackTrace,
131 OUT PULONG BackTraceHash OPTIONAL)
132 {
133 PVOID Frames[2 * 64];
134 ULONG FrameCount;
135 ULONG Hash = 0, i;
136
137 /* Skip a frame for the caller */
138 FramesToSkip++;
139
140 /* Don't go past the limit */
141 if ((FramesToCapture + FramesToSkip) >= 128) return 0;
142
143 /* Do the back trace */
144 FrameCount = RtlWalkFrameChain(Frames, FramesToCapture + FramesToSkip, 0);
145
146 /* Make sure we're not skipping all of them */
147 if (FrameCount <= FramesToSkip) return 0;
148
149 /* Loop all the frames */
150 for (i = 0; i < FramesToCapture; i++)
151 {
152 /* Don't go past the limit */
153 if ((FramesToSkip + i) >= FrameCount) break;
154
155 /* Save this entry and hash it */
156 BackTrace[i] = Frames[FramesToSkip + i];
157 Hash += PtrToUlong(BackTrace[i]);
158 }
159
160 /* Write the hash */
161 if (BackTraceHash) *BackTraceHash = Hash;
162
163 /* Clear the other entries and return count */
164 RtlFillMemoryUlong(Frames, 128, 0);
165 return (USHORT)i;
166 }
167
168 /*
169 * @unimplemented
170 */
171 LONG
172 NTAPI
173 RtlUnhandledExceptionFilter(IN struct _EXCEPTION_POINTERS* ExceptionInfo)
174 {
175 UNIMPLEMENTED;
176 return ERROR_CALL_NOT_IMPLEMENTED;
177 }
178
179 /*
180 * @unimplemented
181 */
182 PVOID
183 NTAPI
184 RtlSetUnhandledExceptionFilter(IN PVOID TopLevelExceptionFilter)
185 {
186 UNIMPLEMENTED;
187 return NULL;
188 }