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>
11 /* INCLUDES *****************************************************************/
18 /* FUNCTIONS ***************************************************************/
20 #if !defined(_M_IX86) && !defined(_M_AMD64)
27 RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord
)
32 /* Capture the context */
33 RtlCaptureContext(&Context
);
35 /* Save the exception address */
36 ExceptionRecord
->ExceptionAddress
= _ReturnAddress();
38 /* Write the context flag */
39 Context
.ContextFlags
= CONTEXT_FULL
;
41 /* Check if user mode debugger is active */
42 if (RtlpCheckForActiveDebugger())
44 /* Raise an exception immediately */
45 Status
= ZwRaiseException(ExceptionRecord
, &Context
, TRUE
);
49 /* Dispatch the exception and check if we should continue */
50 if (!RtlDispatchException(ExceptionRecord
, &Context
))
52 /* Raise the exception */
53 Status
= ZwRaiseException(ExceptionRecord
, &Context
, FALSE
);
57 /* Continue, go back to previous context */
58 Status
= ZwContinue(&Context
, FALSE
);
62 /* If we returned, raise a status */
63 RtlRaiseStatus(Status
);
72 #pragma warning(disable:4717) // RtlRaiseStatus is recursive by design
80 RtlRaiseStatus(IN NTSTATUS Status
)
82 EXCEPTION_RECORD ExceptionRecord
;
85 /* Capture the context */
86 RtlCaptureContext(&Context
);
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
;
95 /* Write the context flag */
96 Context
.ContextFlags
= CONTEXT_FULL
;
98 /* Check if user mode debugger is active */
99 if (RtlpCheckForActiveDebugger())
101 /* Raise an exception immediately */
102 ZwRaiseException(&ExceptionRecord
, &Context
, TRUE
);
106 /* Dispatch the exception */
107 RtlDispatchException(&ExceptionRecord
, &Context
);
109 /* Raise exception if we got here */
110 Status
= ZwRaiseException(&ExceptionRecord
, &Context
, FALSE
);
113 /* If we returned, raise a status */
114 RtlRaiseStatus(Status
);
128 RtlCaptureStackBackTrace(IN ULONG FramesToSkip
,
129 IN ULONG FramesToCapture
,
130 OUT PVOID
*BackTrace
,
131 OUT PULONG BackTraceHash OPTIONAL
)
133 PVOID Frames
[2 * 64];
137 /* Skip a frame for the caller */
140 /* Don't go past the limit */
141 if ((FramesToCapture
+ FramesToSkip
) >= 128) return 0;
143 /* Do the back trace */
144 FrameCount
= RtlWalkFrameChain(Frames
, FramesToCapture
+ FramesToSkip
, 0);
146 /* Make sure we're not skipping all of them */
147 if (FrameCount
<= FramesToSkip
) return 0;
149 /* Loop all the frames */
150 for (i
= 0; i
< FramesToCapture
; i
++)
152 /* Don't go past the limit */
153 if ((FramesToSkip
+ i
) >= FrameCount
) break;
155 /* Save this entry and hash it */
156 BackTrace
[i
] = Frames
[FramesToSkip
+ i
];
157 Hash
+= PtrToUlong(BackTrace
[i
]);
161 if (BackTraceHash
) *BackTraceHash
= Hash
;
163 /* Clear the other entries and return count */
164 RtlFillMemoryUlong(Frames
, 128, 0);
173 RtlUnhandledExceptionFilter(IN
struct _EXCEPTION_POINTERS
* ExceptionInfo
)
176 return ERROR_CALL_NOT_IMPLEMENTED
;
184 RtlSetUnhandledExceptionFilter(IN PVOID TopLevelExceptionFilter
)