Changes: Christian Thalinger
- $Id: stacktrace.c 3325 2005-10-04 18:45:58Z twisti $
+ $Id: stacktrace.c 3570 2005-11-04 16:58:36Z motse $
*/
methodinfo *method;
} lineNumberTableEntryInlineBegin;
-
+#ifndef ENABLE_JVMTI
typedef bool(*CacaoStackTraceCollector)(void **, stackTraceBuffer*);
+#endif
#define BLOCK_INITIALSIZE 40
#define BLOCK_SIZEINCREMENT 40
/* global variables ***********************************************************/
-#if defined(USE_THREADS)
-#define STACKFRAMEINFO (stackframeinfo **) (&THREADINFO->_stackframeinfo)
-#else
-THREADSPECIFIC stackframeinfo *_no_threads_stackframeinfo = NULL;
-
-#define STACKFRAMEINFO (&_no_threads_stackframeinfo)
+#if !defined(USE_THREADS)
+stackframeinfo *_no_threads_stackframeinfo = NULL;
#endif
XXX
*******************************************************************************/
-
+#ifdef ENABLE_JVMTI
+bool cacao_stacktrace_fillInStackTrace(void **target,
+ CacaoStackTraceCollector coll,
+ threadobject* thread)
+#else
static bool cacao_stacktrace_fillInStackTrace(void **target,
- CacaoStackTraceCollector coll)
+ CacaoStackTraceCollector coll)
+#endif
+
{
stacktraceelement primaryBlock[BLOCK_INITIALSIZE*sizeof(stacktraceelement)];
stackTraceBuffer buffer;
/* the first element in the stackframe chain must always be a native */
/* stackframeinfo (VMThrowable.fillInStackTrace is a native function) */
+#ifdef ENABLE_JVMTI
+ if (thread == NULL)
+ sfi = *STACKFRAMEINFO; /* invocation from Throwable */
+ else
+ sfi = thread->info._stackframeinfo; /* invocation from JVMTI */
+#else
sfi = *STACKFRAMEINFO;
+#endif
if (!sfi) {
*target = NULL;
#if PRINTMETHODS
printf("\n\nfillInStackTrace start:\n");
+ fflush(stdout);
#endif
/* loop while we have a method pointer (asm_calljavafunction has NULL) or */
utf_display(m->name);
utf_display(m->descriptor);
printf(": native stub\n");
+ fflush(stdout);
#endif
/* this is an native stub stackframe info, so we can get the */
/* parent pv from the return address (ICMD_INVOKE*) */
#if PRINTMETHODS
printf("NULL: inline stub\n");
+ fflush(stdout);
#endif
/* get methodinfo from current Java method */
utf_display(m->name);
utf_display(m->descriptor);
printf(": inline stub parent\n");
+ fflush(stdout);
#endif
#if defined(ENABLE_INTRP)
}
#endif
}
+#if PRINTMETHODS
+ else {
+ printf("asm_calljavafunction\n");
+ fflush(stdout);
+ }
+#endif
}
/* get previous stackframeinfo in the chain */
XXX
*******************************************************************************/
-
+#ifdef ENABLE_JVMTI
+bool stackTraceCollector(void **target, stackTraceBuffer *buffer)
+#else
static bool stackTraceCollector(void **target, stackTraceBuffer *buffer)
+#endif
{
stackTraceBuffer *dest;
bool cacao_stacktrace_NormalTrace(void **target)
{
+#ifdef ENABLE_JVMTI
+ return cacao_stacktrace_fillInStackTrace(target, &stackTraceCollector, NULL);
+#else
return cacao_stacktrace_fillInStackTrace(target, &stackTraceCollector);
+#endif
+
}
{
java_objectarray *array = NULL;
+#ifdef ENABLE_JVMTI
+ if (!cacao_stacktrace_fillInStackTrace((void **) &array,
+ &classContextCollector, NULL))
+#else
if (!cacao_stacktrace_fillInStackTrace((void **) &array,
&classContextCollector))
+#endif
return NULL;
return array;
{
java_objectheader *header = NULL;
+
+#ifdef ENABLE_JVMTI
+ if (!cacao_stacktrace_fillInStackTrace((void**)&header,
+ &stacktrace_classLoaderCollector,
+ NULL))
+#else
if (!cacao_stacktrace_fillInStackTrace((void**)&header,
&stacktrace_classLoaderCollector))
+#endif
return NULL;
return header;
}
-static bool callingMethodCollector(void **target, stackTraceBuffer *buffer)
-{
- if (buffer->full > 2)
- *target = buffer->start[2].method;
- else
- *target = NULL;
-
- return true;
-}
-
-
-methodinfo *cacao_callingMethod(void)
-{
- methodinfo *method;
-
- if (!cacao_stacktrace_fillInStackTrace((void **) &method,
- &callingMethodCollector))
- return NULL;
-
- return method;
-}
-
-
static bool getStackCollector(void **target, stackTraceBuffer *buffer)
{
java_objectarray *oa;
{
java_objectarray *result = NULL;
+#ifdef ENABLE_JVMTI
+ if (!cacao_stacktrace_fillInStackTrace((void **) &result,
+ &getStackCollector,NULL))
+#else
if (!cacao_stacktrace_fillInStackTrace((void **) &result,
&getStackCollector))
+#endif
return NULL;
return result;
void stacktrace_dump_trace(void)
{
stackTraceBuffer *buffer;
- stacktraceelement *element;
- methodinfo *m;
- s4 i;
#if 0
/* get thread stackframeinfo */
/* print stacktrace */
if (buffer) {
- element = buffer->start;
+ stacktrace_print_trace(buffer);
- for (i = 0; i < buffer->size; i++, element++) {
- m = element->method;
+ } else {
+ puts("\t<<No stacktrace available>>");
+ fflush(stdout);
+ }
+}
- printf("\tat ");
- utf_display_classname(m->class->name);
- printf(".");
- utf_display(m->name);
- utf_display(m->descriptor);
- if (m->flags & ACC_NATIVE) {
- printf("(Native Method)\n");
+/* stacktrace_print_trace ******************************************************
- } else {
- printf("(");
- utf_display(m->class->sourcefile);
- printf(":%d)\n", (u4) element->linenumber);
- }
+ Print the stacktrace of a given stackTraceBuffer with CACAO intern
+ methods (no Java help). This method is used by
+ stacktrace_dump_trace and builtin_trace_exception.
+
+*******************************************************************************/
+
+void stacktrace_print_trace(stackTraceBuffer *stb)
+{
+ stacktraceelement *ste;
+ methodinfo *m;
+ s4 i;
+
+ ste = stb->start;
+
+ for (i = 0; i < stb->size; i++, ste++) {
+ m = ste->method;
+
+ printf("\tat ");
+ utf_display_classname(m->class->name);
+ printf(".");
+ utf_display(m->name);
+ utf_display(m->descriptor);
+
+ if (m->flags & ACC_NATIVE) {
+ puts("(Native Method)");
+
+ } else {
+ printf("(");
+ utf_display(m->class->sourcefile);
+ printf(":%d)\n", (u4) ste->linenumber);
}
}
- /* flush stdout */
+ /* just to be sure */
fflush(stdout);
}