+
+ _Unwind_Backtrace (UnwindTraceFn, &state);
+
+ if (state.trace_data)
+ return (ClassLoader *) state.trace_data;
+
+ return NULL;
+}
+
+struct AccessControlTraceData
+{
+ jint length;
+ jboolean privileged;
+};
+
+_Unwind_Reason_Code
+_Jv_StackTrace::accesscontrol_trace_fn (_Jv_UnwindState *state)
+{
+ AccessControlTraceData *trace_data = (AccessControlTraceData *)
+ state->trace_data;
+ _Jv_StackFrame *frame = &state->frames[state->pos];
+ FillInFrameInfo (frame);
+
+ if (!(frame->klass && frame->meth))
+ return _URC_NO_REASON;
+
+ trace_data->length++;
+
+ // If the previous frame was a call to doPrivileged, then this is
+ // the last frame we look at.
+ if (trace_data->privileged)
+ return _URC_NORMAL_STOP;
+
+ if (frame->klass == &::java::security::AccessController::class$
+ && strcmp (frame->meth->name->chars(), "doPrivileged") == 0)
+ trace_data->privileged = true;
+
+ return _URC_NO_REASON;
+}
+
+jobjectArray
+_Jv_StackTrace::GetAccessControlStack (void)
+{
+ int trace_size = 100;
+ _Jv_StackFrame frames[trace_size];
+ _Jv_UnwindState state (trace_size);
+ state.frames = (_Jv_StackFrame *) &frames;
+
+ AccessControlTraceData trace_data;
+ trace_data.length = 0;
+ trace_data.privileged = false;
+
+ state.trace_function = accesscontrol_trace_fn;
+ state.trace_data = (void *) &trace_data;