- Remove deprecated CHECKPOINT/CHECKPOINT1 macros which basically translated into...
[reactos.git] / reactos / 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 /*
21 * @implemented
22 */
23 VOID
24 NTAPI
25 RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
26 {
27 CONTEXT Context;
28 NTSTATUS Status;
29
30 /* Capture the context */
31 RtlCaptureContext(&Context);
32
33 #ifdef _M_IX86
34 /* Fixup ESP */
35 Context.Esp += sizeof(ULONG);
36 #endif
37
38 /* Save the exception address */
39 ExceptionRecord->ExceptionAddress = RtlpGetExceptionAddress();
40
41 /* Write the context flag */
42 Context.ContextFlags = CONTEXT_FULL;
43
44 /* Check if user mode debugger is active */
45 if (RtlpCheckForActiveDebugger(FALSE))
46 {
47 /* Raise an exception immediately */
48 Status = ZwRaiseException(ExceptionRecord, &Context, TRUE);
49 }
50 else
51 {
52 /* Dispatch the exception and check if we should continue */
53 if (!RtlDispatchException(ExceptionRecord, &Context))
54 {
55 /* Raise the exception */
56 Status = ZwRaiseException(ExceptionRecord, &Context, FALSE);
57 }
58 else
59 {
60 /* Continue, go back to previous context */
61 Status = ZwContinue(&Context, FALSE);
62 }
63 }
64
65 /* If we returned, raise a status */
66 RtlRaiseStatus(Status);
67 }
68
69 /*
70 * @implemented
71 */
72 VOID
73 NTAPI
74 RtlRaiseStatus(NTSTATUS Status)
75 {
76 EXCEPTION_RECORD ExceptionRecord;
77 CONTEXT Context;
78
79 /* Capture the context */
80 RtlCaptureContext(&Context);
81
82 #ifdef _M_IX86
83 /* Add one argument to ESP */
84 Context.Esp += sizeof(PVOID);
85 #endif
86
87 /* Create an exception record */
88 ExceptionRecord.ExceptionAddress = RtlpGetExceptionAddress();
89 ExceptionRecord.ExceptionCode = Status;
90 ExceptionRecord.ExceptionRecord = NULL;
91 ExceptionRecord.NumberParameters = 0;
92 ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
93
94 /* Write the context flag */
95 Context.ContextFlags = CONTEXT_FULL;
96
97 /* Check if user mode debugger is active */
98 if (RtlpCheckForActiveDebugger(FALSE))
99 {
100 /* Raise an exception immediately */
101 ZwRaiseException(&ExceptionRecord, &Context, TRUE);
102 }
103 else
104 {
105 /* Dispatch the exception */
106 RtlDispatchException(&ExceptionRecord, &Context);
107
108 /* Raise exception if we got here */
109 Status = ZwRaiseException(&ExceptionRecord, &Context, FALSE);
110 }
111
112 /* If we returned, raise a status */
113 RtlRaiseStatus(Status);
114 }
115
116 /*
117 * @implemented
118 */
119 USHORT
120 NTAPI
121 RtlCaptureStackBackTrace(IN ULONG FramesToSkip,
122 IN ULONG FramesToCapture,
123 OUT PVOID *BackTrace,
124 OUT PULONG BackTraceHash OPTIONAL)
125 {
126 PVOID Frames[2 * 64];
127 ULONG FrameCount;
128 ULONG Hash = 0, i;
129
130 /* Skip a frame for the caller */
131 FramesToSkip++;
132
133 /* Don't go past the limit */
134 if ((FramesToCapture + FramesToSkip) >= 128) return 0;
135
136 /* Do the back trace */
137 FrameCount = RtlWalkFrameChain(Frames, FramesToCapture + FramesToSkip, 0);
138
139 /* Make sure we're not skipping all of them */
140 if (FrameCount <= FramesToSkip) return 0;
141
142 /* Loop all the frames */
143 for (i = 0; i < FramesToCapture; i++)
144 {
145 /* Don't go past the limit */
146 if ((FramesToSkip + i) >= FrameCount) break;
147
148 /* Save this entry and hash it */
149 BackTrace[i] = Frames[FramesToSkip + i];
150 Hash += PtrToUlong(BackTrace[i]);
151 }
152
153 /* Write the hash */
154 if (BackTraceHash) *BackTraceHash = Hash;
155
156 /* Clear the other entries and return count */
157 RtlFillMemoryUlong(Frames, 128, 0);
158 return (USHORT)i;
159 }
160
161 /*
162 * @unimplemented
163 */
164 LONG
165 NTAPI
166 RtlUnhandledExceptionFilter(IN struct _EXCEPTION_POINTERS* ExceptionInfo)
167 {
168 UNIMPLEMENTED;
169 return ERROR_CALL_NOT_IMPLEMENTED;
170 }
171
172 /* EOF */