diff options
author | Andrew Haley <aph@redhat.com> | 2016-09-30 16:24:48 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2016-09-30 16:24:48 +0000 |
commit | 07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch) | |
tree | 3f22b3241c513ad168c8353805614ae1249410f4 /libjava/stacktrace.cc | |
parent | eae993948bae8b788c53772bcb9217c063716f93 (diff) | |
download | gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.zip gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.gz gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.bz2 |
Makefile.def: Remove libjava.
2016-09-30 Andrew Haley <aph@redhat.com>
* Makefile.def: Remove libjava.
* Makefile.tpl: Likewise.
* Makefile.in: Regenerate.
* configure.ac: Likewise.
* configure: Likewise.
* gcc/java: Remove.
* libjava: Likewise.
From-SVN: r240662
Diffstat (limited to 'libjava/stacktrace.cc')
-rw-r--r-- | libjava/stacktrace.cc | 828 |
1 files changed, 0 insertions, 828 deletions
diff --git a/libjava/stacktrace.cc b/libjava/stacktrace.cc deleted file mode 100644 index 0fc91c4..0000000 --- a/libjava/stacktrace.cc +++ /dev/null @@ -1,828 +0,0 @@ -// stacktrace.cc - Functions for unwinding & inspecting the call stack. - -/* Copyright (C) 2005, 2006 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -#include <config.h> -#include <platform.h> - -#include <jvm.h> -#include <gcj/cni.h> -#include <java-interp.h> -#include <java-stack.h> - -#include <stdio.h> - -#include <java/lang/Boolean.h> -#include <java/lang/Class.h> -#include <java/lang/Long.h> -#include <java/lang/reflect/Method.h> -#include <java/security/AccessController.h> -#include <java/util/ArrayList.h> -#include <java/util/IdentityHashMap.h> -#include <gnu/classpath/jdwp/Jdwp.h> -#include <gnu/classpath/VMStackWalker.h> -#include <gnu/java/lang/MainThread.h> -#include <gnu/gcj/runtime/NameFinder.h> -#include <gnu/gcj/runtime/StringBuffer.h> - -#include <sysdep/backtrace.h> -#include <sysdep/descriptor.h> - -using namespace java::lang; -using namespace java::lang::reflect; -using namespace java::util; -using namespace gnu::gcj::runtime; - -#ifdef __ARM_EABI_UNWINDER__ -#define _URC_NORMAL_STOP _URC_FAILURE -#endif - -// Maps ncode values to their containing native class. -// NOTE: Currently this Map contradicts class GC for native classes. This map -// (and the "new class stack") will need to use WeakReferences in order to -// enable native class GC. -java::util::IdentityHashMap *_Jv_StackTrace::ncodeMap; - -// Check the "class stack" for any classes initialized since we were last -// called, and add them to ncodeMap. -void -_Jv_StackTrace::UpdateNCodeMap () -{ - // The Map should be large enough so that a typical Java app doesn't cause - // it to rehash, without using too much memory. ~5000 entries should be - // enough. - if (ncodeMap == NULL) - ncodeMap = new java::util::IdentityHashMap (5087); - - jclass klass; - while ((klass = _Jv_PopClass ())) - { - //printf ("got %s\n", klass->name->data); - for (int i = 0; i < klass->method_count; i++) - { - _Jv_Method *method = &klass->methods[i]; - void *ncode = method->ncode; - // Add non-abstract methods to ncodeMap. - if (ncode) - { - ncode = UNWRAP_FUNCTION_DESCRIPTOR (ncode); - ncodeMap->put ((java::lang::Object *) ncode, klass); - } - } - } -} - -// Given a native frame, return the class which this code belongs -// to. Returns NULL if this IP is not associated with a native Java class. -// If NCODE is supplied, it will be set with the ip for the entry point of the -// enclosing method. -jclass -_Jv_StackTrace::ClassForFrame (_Jv_StackFrame *frame) -{ - JvAssert (frame->type == frame_native); - jclass klass = NULL; - - // look it up in ncodeMap - if (frame->start_ip) - { - klass = (jclass) ncodeMap->get ((jobject) frame->start_ip); - - // Exclude interpreted classes - if (klass != NULL && _Jv_IsInterpretedClass (klass)) - klass = NULL; - } - - return klass; -} - -_Unwind_Reason_Code -_Jv_StackTrace::UnwindTraceFn (struct _Unwind_Context *context, void *state_ptr) -{ - _Jv_UnwindState *state = (_Jv_UnwindState *) state_ptr; - jint pos = state->pos; - - // Check if the trace buffer needs to be extended. - if (pos == state->length) - { - int newLength = state->length * 2; - void *newFrames = _Jv_AllocBytes (newLength * sizeof(_Jv_StackFrame)); - memcpy (newFrames, state->frames, state->length * sizeof(_Jv_StackFrame)); - state->frames = (_Jv_StackFrame *) newFrames; - state->length = newLength; - } - - void *func_addr = (void *) _Unwind_GetRegionStart (context); - - // If we see the interpreter's main function, "pop" an entry off the - // interpreter stack and use that instead, so that the trace goes through - // the java code and not the interpreter itself. This assumes a 1:1 - // correspondance between call frames in the interpreted stack and occurances - // of _Jv_InterpMethod::run() on the native stack. -#ifdef INTERPRETER - void *interp_run = NULL; - - if (::gnu::classpath::jdwp::Jdwp::isDebugging) - interp_run = (void *) &_Jv_InterpMethod::run_debug; - else - interp_run = (void *) &_Jv_InterpMethod::run; - - if (func_addr == UNWRAP_FUNCTION_DESCRIPTOR (interp_run)) - { - state->frames[pos].type = frame_interpreter; - _Jv_Frame *frame = static_cast<_Jv_Frame *> (state->interp_frame); - state->frames[pos].interp.meth - = static_cast<_Jv_InterpMethod *> (frame->self); - state->frames[pos].interp.pc = state->interp_frame->pc; - state->interp_frame = state->interp_frame->next_interp; - } - else - // We handle proxies in the same way as interpreted classes - if (_Jv_is_proxy (func_addr)) - { - state->frames[pos].type = frame_proxy; - state->frames[pos].proxyClass = state->interp_frame->proxyClass; - state->frames[pos].proxyMethod = state->interp_frame->proxyMethod; - state->interp_frame = state->interp_frame->next_interp; - } - else -#endif - { -#ifdef HAVE_GETIPINFO - _Unwind_Ptr ip; - int ip_before_insn = 0; - ip = _Unwind_GetIPInfo (context, &ip_before_insn); - - // If the unwinder gave us a 'return' address, roll it back a little - // to ensure we get the correct line number for the call itself. - if (! ip_before_insn) - --ip; -#endif - state->frames[pos].type = frame_native; -#ifdef HAVE_GETIPINFO - state->frames[pos].ip = (void *) ip; -#else - state->frames[pos].ip = (void *) _Unwind_GetIP (context); -#endif - state->frames[pos].start_ip = func_addr; - } - - _Unwind_Reason_Code result = _URC_NO_REASON; - if (state->trace_function != NULL) - result = (state->trace_function) (state); - state->pos++; - return result; -} - -// Return a raw stack trace from the current point of execution. The raw -// trace will include all functions that have unwind info. -_Jv_StackTrace * -_Jv_StackTrace::GetStackTrace(void) -{ - int trace_size = 100; - _Jv_StackFrame frames[trace_size]; - _Jv_UnwindState state (trace_size); - state.frames = (_Jv_StackFrame *) &frames; - - _Unwind_Backtrace (UnwindTraceFn, &state); - - // Copy the trace and return it. - int traceSize = sizeof (_Jv_StackTrace) + - (sizeof (_Jv_StackFrame) * state.pos); - _Jv_StackTrace *trace = (_Jv_StackTrace *) _Jv_AllocBytes (traceSize); - trace->length = state.pos; - memcpy (trace->frames, state.frames, sizeof (_Jv_StackFrame) * state.pos); - return trace; -} - -void -_Jv_StackTrace::getLineNumberForFrame(_Jv_StackFrame *frame, NameFinder *finder, - jstring *sourceFileName, jint *lineNum, - jstring *methodName) -{ -#ifdef INTERPRETER - if (frame->type == frame_interpreter) - { - _Jv_InterpMethod *interp_meth = frame->interp.meth; - _Jv_InterpClass *interp_class = - (_Jv_InterpClass *) interp_meth->defining_class->aux_info; - *sourceFileName = interp_class->source_file_name; - // The interpreter advances the PC before executing an instruction, - // so roll-back 1 byte to ensure the line number is accurate. - *lineNum = interp_meth->get_source_line(frame->interp.pc - 1); - return; - } -#endif - - if (frame->type == frame_proxy) - { - *sourceFileName = NULL; - *lineNum = 0; - return; - } - - // Use _Jv_platform_dladdr() to determine in which binary the address IP - // resides. - _Jv_AddrInfo info; - jstring binaryName = NULL; - const char *argv0 = _Jv_GetSafeArg(0); - - void *ip = frame->ip; - _Unwind_Ptr offset = 0; - - if (_Jv_platform_dladdr (ip, &info)) - { - if (info.file_name) - binaryName = JvNewStringUTF (info.file_name); - else - return; - - if (*methodName == NULL && info.sym_name) - *methodName = JvNewStringUTF (info.sym_name); - - // addr2line expects relative addresses for shared libraries. - if (strcmp (info.file_name, argv0) == 0) - offset = (_Unwind_Ptr) ip; - else - offset = (_Unwind_Ptr) ip - (_Unwind_Ptr) info.base; - -#ifndef HAVE_GETIPINFO - // The unwinder gives us the return address. In order to get the right - // line number for the stack trace, roll it back a little. - offset -= 1; -#endif - - finder->lookup (binaryName, (jlong) offset); - *sourceFileName = finder->getSourceFile(); - *lineNum = finder->getLineNum(); - if (*lineNum == -1 && NameFinder::showRaw()) - { - gnu::gcj::runtime::StringBuffer *t = - new gnu::gcj::runtime::StringBuffer(binaryName); - t->append ((jchar)' '); - t->append ((jchar)'['); - // + 1 to compensate for the - 1 adjustment above; - t->append (Long::toHexString (offset + 1)); - t->append ((jchar)']'); - *sourceFileName = t->toString(); - } - } -} - -// Look up class and method info for the given stack frame, setting -// frame->klass and frame->meth if they are known. -void -_Jv_StackTrace::FillInFrameInfo (_Jv_StackFrame *frame) -{ - jclass klass = NULL; - _Jv_Method *meth = NULL; - - if (frame->type == frame_native) - { - klass = _Jv_StackTrace::ClassForFrame (frame); - - if (klass != NULL) - // Find method in class - for (int j = 0; j < klass->method_count; j++) - { - void *wncode = UNWRAP_FUNCTION_DESCRIPTOR (klass->methods[j].ncode); - if (wncode == frame->start_ip) - { - meth = &klass->methods[j]; - break; - } - } - } - else if (frame->type == frame_proxy) - { - klass = frame->proxyClass; - meth = frame->proxyMethod; - } -#ifdef INTERPRETER - else if (frame->type == frame_interpreter) - { - _Jv_InterpMethod *interp_meth = frame->interp.meth; - klass = interp_meth->defining_class; - meth = interp_meth->self; - } -#endif - else - JvFail ("Unknown frame type"); - - frame->klass = klass; - frame->meth = meth; -} - -// Convert raw stack frames to a Java array of StackTraceElement objects. -JArray< ::java::lang::StackTraceElement *>* -_Jv_StackTrace::GetStackTraceElements (_Jv_StackTrace *trace, - Throwable *throwable __attribute__((unused))) -{ - ArrayList *list = new ArrayList (); - -#if defined (__USING_SJLJ_EXCEPTIONS__) && ! defined (WIN32) - // We can't use the nCodeMap without unwinder support. Instead, - // fake the method name by giving the IP in hex - better than nothing. - jstring hex = JvNewStringUTF ("0x"); - - for (int i = 0; i < trace->length; i++) - { - jstring sourceFileName = NULL; - jint lineNum = -1; - _Jv_StackFrame *frame = &trace->frames[i]; - - jstring className = NULL; - jstring methodName = hex->concat (Long::toHexString ((jlong) frame->ip)); - - StackTraceElement *element = new StackTraceElement (sourceFileName, - lineNum, className, methodName, 0); - list->add (element); - } - -#else /* __USING_SJLJ_EXCEPTIONS__ && !WIN32 */ - - //JvSynchronized (ncodeMap); - UpdateNCodeMap (); - - NameFinder *finder = new NameFinder(); - int start_idx = 0; - int end_idx = trace->length - 1; - - // First pass: strip superfluous frames from beginning and end of the trace. - for (int i = 0; i < trace->length; i++) - { - _Jv_StackFrame *frame = &trace->frames[i]; - FillInFrameInfo (frame); - - if (!frame->klass || !frame->meth) - // Not a Java frame. - continue; - - // Throw away the top of the stack till we see: - // - the constructor(s) of this Throwable, or - // - the Throwable.fillInStackTrace call. - if (frame->klass == throwable->getClass() - && strcmp (frame->meth->name->chars(), "<init>") == 0) - start_idx = i + 1; - - if (frame->klass == &Throwable::class$ - && strcmp (frame->meth->name->chars(), "fillInStackTrace") == 0) - start_idx = i + 1; - - // End the trace at the application's main() method if we see call_main. - if (frame->klass == &gnu::java::lang::MainThread::class$ - && strcmp (frame->meth->name->chars(), "call_main") == 0) - end_idx = i - 1; - } - - const jboolean remove_unknown - = gnu::gcj::runtime::NameFinder::removeUnknown(); - - // Second pass: Look up line-number info for remaining frames. - for (int i = start_idx; i <= end_idx; i++) - { - _Jv_StackFrame *frame = &trace->frames[i]; - - if (frame->klass == NULL && remove_unknown) - // Not a Java frame. - continue; - - jstring className = NULL; - if (frame->klass != NULL) - className = frame->klass->getName (); - - jstring methodName = NULL; - if (frame->meth) - methodName = JvNewStringUTF (frame->meth->name->chars()); - - jstring sourceFileName = NULL; - jint lineNum = -1; - - getLineNumberForFrame(frame, finder, &sourceFileName, &lineNum, - &methodName); - - StackTraceElement *element = new StackTraceElement (sourceFileName, lineNum, - className, methodName, 0); - list->add (element); - } - - finder->close(); -#endif /* __USING_SJLJ_EXCEPTIONS__ && !WIN32 */ - - JArray<Object *> *array = JvNewObjectArray (list->size (), - &StackTraceElement::class$, NULL); - - return (JArray<StackTraceElement *>*) list->toArray (array); -} - -struct CallingClassTraceData -{ - jclass checkClass; - jclass foundClass; - _Jv_Method *foundMeth; - bool seen_checkClass; -}; - -_Unwind_Reason_Code -_Jv_StackTrace::calling_class_trace_fn (_Jv_UnwindState *state) -{ - CallingClassTraceData *trace_data = (CallingClassTraceData *) - state->trace_data; - _Jv_StackFrame *frame = &state->frames[state->pos]; - FillInFrameInfo (frame); - - if (trace_data->seen_checkClass - && frame->klass - && frame->klass != trace_data->checkClass) - { - trace_data->foundClass = frame->klass; - trace_data->foundMeth = frame->meth; - return _URC_NORMAL_STOP; - } - - if (frame->klass == trace_data->checkClass) - trace_data->seen_checkClass = true; - - return _URC_NO_REASON; -} - -// Find the class immediately above the given class on the call stack. Any -// intermediate non-Java -// frames are ignored. If the calling class could not be determined (eg because -// the unwinder is not supported on this platform), NULL is returned. -// This function is used to implement calling-classloader checks and reflection -// accessibility checks. -// CHECKCLASS is typically the class calling GetCallingClass. The first class -// above CHECKCLASS on the call stack will be returned. -jclass -_Jv_StackTrace::GetCallingClass (jclass checkClass) -{ - jclass result = NULL; - GetCallerInfo (checkClass, &result, NULL); - return result; -} - -void -_Jv_StackTrace::GetCallerInfo (jclass checkClass, jclass *caller_class, - _Jv_Method **caller_meth) -{ - int trace_size = 20; - _Jv_StackFrame frames[trace_size]; - _Jv_UnwindState state (trace_size); - state.frames = (_Jv_StackFrame *) &frames; - - CallingClassTraceData trace_data; - trace_data.checkClass = checkClass; - trace_data.seen_checkClass = false; - trace_data.foundClass = NULL; - trace_data.foundMeth = NULL; - - state.trace_function = calling_class_trace_fn; - state.trace_data = (void *) &trace_data; - - //JvSynchronized (ncodeMap); - UpdateNCodeMap (); - - _Unwind_Backtrace (UnwindTraceFn, &state); - - if (caller_class) - *caller_class = trace_data.foundClass; - if (caller_meth) - *caller_meth = trace_data.foundMeth; -} - -_Unwind_Reason_Code -_Jv_StackTrace::non_system_trace_fn (_Jv_UnwindState *state) -{ - _Jv_StackFrame *frame = &state->frames[state->pos]; - FillInFrameInfo (frame); - - ClassLoader *classLoader = NULL; - - if (frame->klass) - { - classLoader = frame->klass->getClassLoaderInternal(); -#ifdef INTERPRETER - if (classLoader != NULL) - { - state->trace_data = (void *) classLoader; - return _URC_NORMAL_STOP; - } -#endif - } - - return _URC_NO_REASON; -} - -ClassLoader * -_Jv_StackTrace::GetFirstNonSystemClassLoader () -{ - int trace_size = 32; - _Jv_StackFrame frames[trace_size]; - _Jv_UnwindState state (trace_size); - state.frames = (_Jv_StackFrame *) &frames; - state.trace_function = non_system_trace_fn; - state.trace_data = NULL; - - //JvSynchronized (ncodeMap); - UpdateNCodeMap (); - - _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; - - UpdateNCodeMap(); - _Unwind_Backtrace (UnwindTraceFn, &state); - - JArray<jclass> *classes = (JArray<jclass> *) - _Jv_NewObjectArray (trace_data.length, &::java::lang::Class::class$, NULL); - jclass *c = elements (classes); - - for (int i = 0, j = 0; i < state.pos; i++) - { - _Jv_StackFrame *frame = &state.frames[i]; - if (!frame->klass || !frame->meth) - continue; - c[j] = frame->klass; - j++; - } - - jobjectArray result = - (jobjectArray) _Jv_NewObjectArray (2, &::java::lang::Object::class$, - NULL); - jobject *r = elements (result); - r[0] = (jobject) classes; - r[1] = (jobject) new Boolean (trace_data.privileged); - - return result; -} - -JArray<jclass> * -_Jv_StackTrace::GetStackWalkerStack () -{ - int trace_size = 100; - _Jv_StackFrame frames[trace_size]; - _Jv_UnwindState state (trace_size); - state.frames = (_Jv_StackFrame *) &frames; - - UpdateNCodeMap (); - _Unwind_Backtrace (UnwindTraceFn, &state); - - int num_frames = 0, start_frame = -1; - enum - { - VMSW_GETCLASSCONTEXT, - JLRM_INVOKE_OR_USER_FN, - USER_FN - } - expect = VMSW_GETCLASSCONTEXT; - for (int i = 0; i < state.pos; i++) - { - _Jv_StackFrame *frame = &state.frames[i]; - FillInFrameInfo (frame); - if (!frame->klass || !frame->meth) - continue; - - switch (expect) - { - case VMSW_GETCLASSCONTEXT: - JvAssert ( - frame->klass == &::gnu::classpath::VMStackWalker::class$ - && strcmp (frame->meth->name->chars(), "getClassContext") == 0); - expect = JLRM_INVOKE_OR_USER_FN; - break; - - case JLRM_INVOKE_OR_USER_FN: - if (frame->klass != &::java::lang::reflect::Method::class$ - || strcmp (frame->meth->name->chars(), "invoke") != 0) - start_frame = i; - expect = USER_FN; - break; - - case USER_FN: - if (start_frame == -1) - start_frame = i; - break; - } - - if (start_frame != -1) - { - if (frame->klass == &::gnu::java::lang::MainThread::class$) - break; - num_frames++; - } - } - JvAssert (num_frames > 0 && start_frame > 0); - - JArray<jclass> *result = (JArray<jclass> *) - _Jv_NewObjectArray (num_frames, &::java::lang::Class::class$, NULL); - jclass *c = elements (result); - - for (int i = start_frame, j = 0; i < state.pos && j < num_frames; i++) - { - _Jv_StackFrame *frame = &state.frames[i]; - if (!frame->klass || !frame->meth) - continue; - c[j] = frame->klass; - j++; - } - - return result; -} - -typedef enum - { - VMSW_GET_CALLING_ITEM, - JLRM_INVOKE_OR_CALLER, - CALLER, - CALLER_OF_CALLER - } gswcc_expect; - -struct StackWalkerTraceData -{ - gswcc_expect expect; - jclass result; -}; - -_Unwind_Reason_Code -_Jv_StackTrace::stackwalker_trace_fn (_Jv_UnwindState *state) -{ - StackWalkerTraceData *trace_data = (StackWalkerTraceData *) - state->trace_data; - _Jv_StackFrame *frame = &state->frames[state->pos]; - FillInFrameInfo (frame); - - if (!(frame->klass && frame->meth)) - return _URC_NO_REASON; - - switch (trace_data->expect) - { - case VMSW_GET_CALLING_ITEM: - JvAssert (frame->klass == &::gnu::classpath::VMStackWalker::class$); - trace_data->expect = JLRM_INVOKE_OR_CALLER; - break; - - case JLRM_INVOKE_OR_CALLER: - if (frame->klass == &::java::lang::reflect::Method::class$ - && strcmp (frame->meth->name->chars(), "invoke") == 0) - trace_data->expect = CALLER; - else - trace_data->expect = CALLER_OF_CALLER; - break; - - case CALLER: - trace_data->expect = CALLER_OF_CALLER; - break; - - case CALLER_OF_CALLER: - trace_data->result = frame->klass; - return _URC_NORMAL_STOP; - } - - return _URC_NO_REASON; -} - -jclass -_Jv_StackTrace::GetStackWalkerCallingClass (void) -{ - int trace_size = 100; - _Jv_StackFrame frames[trace_size]; - _Jv_UnwindState state (trace_size); - state.frames = (_Jv_StackFrame *) &frames; - - StackWalkerTraceData trace_data; - trace_data.expect = VMSW_GET_CALLING_ITEM; - trace_data.result = NULL; - - state.trace_function = stackwalker_trace_fn; - state.trace_data = (void *) &trace_data; - - UpdateNCodeMap(); - _Unwind_Backtrace (UnwindTraceFn, &state); - - return trace_data.result; -} - -struct StackWalkerNNLTraceData -{ - gswcc_expect expect; - ClassLoader *result; -}; - -_Unwind_Reason_Code -_Jv_StackTrace::stackwalker_nnl_trace_fn (_Jv_UnwindState *state) -{ - StackWalkerNNLTraceData *trace_data = (StackWalkerNNLTraceData *) - state->trace_data; - _Jv_StackFrame *frame = &state->frames[state->pos]; - FillInFrameInfo (frame); - - if (!(frame->klass && frame->meth)) - return _URC_NO_REASON; - - switch (trace_data->expect) - { - case VMSW_GET_CALLING_ITEM: - JvAssert (frame->klass == &::gnu::classpath::VMStackWalker::class$); - trace_data->expect = JLRM_INVOKE_OR_CALLER; - break; - - case JLRM_INVOKE_OR_CALLER: - if (frame->klass == &::java::lang::reflect::Method::class$ - && strcmp (frame->meth->name->chars(), "invoke") == 0) - trace_data->expect = CALLER; - else - trace_data->expect = CALLER_OF_CALLER; - break; - - case CALLER: - trace_data->expect = CALLER_OF_CALLER; - break; - - case CALLER_OF_CALLER: - ClassLoader *cl = frame->klass->getClassLoaderInternal (); - if (cl != NULL) - { - trace_data->result = cl; - return _URC_NORMAL_STOP; - } - } - - return _URC_NO_REASON; -} - -ClassLoader * -_Jv_StackTrace::GetStackWalkerFirstNonNullLoader (void) -{ - int trace_size = 100; - _Jv_StackFrame frames[trace_size]; - _Jv_UnwindState state (trace_size); - state.frames = (_Jv_StackFrame *) &frames; - - StackWalkerNNLTraceData trace_data; - trace_data.expect = VMSW_GET_CALLING_ITEM; - trace_data.result = NULL; - - state.trace_function = stackwalker_nnl_trace_fn; - state.trace_data = (void *) &trace_data; - - UpdateNCodeMap(); - _Unwind_Backtrace (UnwindTraceFn, &state); - - return trace_data.result; -} |