| // java-stack.h - Definitions 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. */ | |
| #ifndef __JV_STACKTRACE_H__ | |
| #define __JV_STACKTRACE_H__ | |
| #include <stdlib.h> | |
| #include <unwind.h> | |
| #include <gcj/cni.h> | |
| #include <gcj/javaprims.h> | |
| #include <java-interp.h> | |
| #include <java/lang/Class.h> | |
| #include <java/lang/StackTraceElement.h> | |
| #include <java/lang/Throwable.h> | |
| #include <java/lang/Thread.h> | |
| #include <gnu/gcj/runtime/NameFinder.h> | |
| using namespace gnu::gcj::runtime; | |
| using namespace java::lang; | |
| enum _Jv_FrameType | |
| { | |
| frame_native, | |
| frame_interpreter | |
| }; | |
| #ifdef INTERPRETER | |
| struct _Jv_InterpFrameInfo | |
| { | |
| _Jv_InterpMethod *meth; | |
| pc_t pc; | |
| }; | |
| #endif | |
| union _Jv_FrameInfo | |
| { | |
| }; | |
| struct _Jv_StackFrame | |
| { | |
| _Jv_FrameType type; /* Native or interpreted. */ | |
| union { | |
| #ifdef INTERPRETER | |
| _Jv_InterpFrameInfo interp; | |
| #endif | |
| struct { | |
| void *ip; | |
| void *start_ip; | |
| }; | |
| }; | |
| // _Jv_FrameInfo info; /* Frame-type specific data. */ | |
| jclass klass; | |
| _Jv_Method *meth; | |
| }; | |
| typedef struct _Jv_UnwindState; | |
| typedef _Unwind_Reason_Code (*_Jv_TraceFn) (_Jv_UnwindState *); | |
| struct _Jv_UnwindState | |
| { | |
| jint length; // length of FRAMES | |
| jint pos; // current position in FRAMES | |
| _Jv_StackFrame *frames; // array of stack frame data to be filled. | |
| #ifdef INTERPRETER | |
| _Jv_InterpFrame *interp_frame; // current frame in the interpreter stack. | |
| #endif | |
| _Jv_TraceFn trace_function; // function to call back after each frame | |
| // is enumerated. May be NULL. | |
| void *trace_data; // additional state data for trace_function. | |
| _Jv_UnwindState (jint ln) | |
| { | |
| length = ln; | |
| pos = 0; | |
| frames = NULL; | |
| Thread *thread = Thread::currentThread(); | |
| // Check for NULL currentThread(), in case an exception is created | |
| // very early during the runtime startup. | |
| #ifdef INTERPRETER | |
| if (thread) | |
| interp_frame = (_Jv_InterpFrame *) thread->interp_frame; | |
| #endif | |
| trace_function = NULL; | |
| trace_data = NULL; | |
| } | |
| }; | |
| class _Jv_StackTrace | |
| { | |
| private: | |
| int length; | |
| _Jv_StackFrame frames[]; | |
| static void UpdateNCodeMap (); | |
| static jclass ClassForFrame (_Jv_StackFrame *frame); | |
| static void FillInFrameInfo (_Jv_StackFrame *frame); | |
| static void getLineNumberForFrame(_Jv_StackFrame *frame, NameFinder *finder, | |
| jstring *sourceFileName, jint *lineNum, | |
| jstring *methodName); | |
| static _Unwind_Reason_Code UnwindTraceFn (struct _Unwind_Context *context, | |
| void *state_ptr); | |
| static _Unwind_Reason_Code calling_class_trace_fn (_Jv_UnwindState *state); | |
| static _Unwind_Reason_Code non_system_trace_fn (_Jv_UnwindState *state); | |
| static _Unwind_Reason_Code accesscontrol_trace_fn (_Jv_UnwindState *state); | |
| public: | |
| static _Jv_StackTrace *GetStackTrace (void); | |
| static JArray< ::java::lang::StackTraceElement *>* | |
| GetStackTraceElements (_Jv_StackTrace *trace, | |
| java::lang::Throwable *throwable); | |
| static jclass GetCallingClass (jclass); | |
| static void GetCallerInfo (jclass checkClass, jclass *, _Jv_Method **); | |
| static JArray<jclass> *GetClassContext (jclass checkClass); | |
| static ClassLoader *GetFirstNonSystemClassLoader (void); | |
| static jobjectArray GetAccessControlStack (); | |
| }; | |
| // Information about a given address. | |
| struct _Jv_AddrInfo | |
| { | |
| // File name of the defining module. | |
| const char *file_name; | |
| // Base address of the loaded module. | |
| void *base; | |
| // Name of the nearest symbol. | |
| const char *sym_name; | |
| // Address of the nearest symbol. | |
| void *sym_addr; | |
| ~_Jv_AddrInfo (void) | |
| { | |
| // On systems with a real dladdr(), the file and symbol names given by | |
| // _Jv_platform_dladdr() are not dynamically allocated. On Windows, | |
| // they are. | |
| #ifdef WIN32 | |
| if (file_name) | |
| free ((void *)file_name); | |
| if (sym_name) | |
| free ((void *)sym_name); | |
| #endif /* WIN32 */ | |
| } | |
| }; | |
| #endif /* __JV_STACKTRACE_H__ */ |