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 ***************************************************************/
25 RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord
)
30 /* Capture the context */
31 RtlCaptureContext(&Context
);
35 Context
.Esp
+= sizeof(ULONG
);
38 /* Save the exception address */
39 ExceptionRecord
->ExceptionAddress
= RtlpGetExceptionAddress();
41 /* Write the context flag */
42 Context
.ContextFlags
= CONTEXT_FULL
;
44 /* Check if user mode debugger is active */
45 if (RtlpCheckForActiveDebugger(FALSE
))
47 /* Raise an exception immediately */
48 Status
= ZwRaiseException(ExceptionRecord
, &Context
, TRUE
);
52 /* Dispatch the exception and check if we should continue */
53 if (!RtlDispatchException(ExceptionRecord
, &Context
))
55 /* Raise the exception */
56 Status
= ZwRaiseException(ExceptionRecord
, &Context
, FALSE
);
60 /* Continue, go back to previous context */
61 Status
= ZwContinue(&Context
, FALSE
);
65 /* If we returned, raise a status */
66 RtlRaiseStatus(Status
);
74 RtlRaiseStatus(NTSTATUS Status
)
76 EXCEPTION_RECORD ExceptionRecord
;
79 /* Capture the context */
80 RtlCaptureContext(&Context
);
83 /* Add one argument to ESP */
84 Context
.Esp
+= sizeof(PVOID
);
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
;
94 /* Write the context flag */
95 Context
.ContextFlags
= CONTEXT_FULL
;
97 /* Check if user mode debugger is active */
98 if (RtlpCheckForActiveDebugger(FALSE
))
100 /* Raise an exception immediately */
101 ZwRaiseException(&ExceptionRecord
, &Context
, TRUE
);
105 /* Dispatch the exception */
106 RtlDispatchException(&ExceptionRecord
, &Context
);
108 /* Raise exception if we got here */
109 Status
= ZwRaiseException(&ExceptionRecord
, &Context
, FALSE
);
112 /* If we returned, raise a status */
113 RtlRaiseStatus(Status
);
121 RtlCaptureStackBackTrace(IN ULONG FramesToSkip
,
122 IN ULONG FramesToCapture
,
123 OUT PVOID
*BackTrace
,
124 OUT PULONG BackTraceHash OPTIONAL
)
126 PVOID Frames
[2 * 64];
130 /* Skip a frame for the caller */
133 /* Don't go past the limit */
134 if ((FramesToCapture
+ FramesToSkip
) >= 128) return 0;
136 /* Do the back trace */
137 FrameCount
= RtlWalkFrameChain(Frames
, FramesToCapture
+ FramesToSkip
, 0);
139 /* Make sure we're not skipping all of them */
140 if (FrameCount
<= FramesToSkip
) return 0;
142 /* Loop all the frames */
143 for (i
= 0; i
< FramesToCapture
; i
++)
145 /* Don't go past the limit */
146 if ((FramesToSkip
+ i
) >= FrameCount
) break;
148 /* Save this entry and hash it */
149 BackTrace
[i
] = Frames
[FramesToSkip
+ i
];
150 Hash
+= PtrToUlong(BackTrace
[i
]);
154 if (BackTraceHash
) *BackTraceHash
= Hash
;
156 /* Clear the other entries and return count */
157 RtlFillMemoryUlong(Frames
, 128, 0);
166 RtlUnhandledExceptionFilter(IN
struct _EXCEPTION_POINTERS
* ExceptionInfo
)
169 return ERROR_CALL_NOT_IMPLEMENTED
;