Fix VMStackWalker.getClassContext()
Andrew Haley
aph@redhat.com
Wed Jan 24 12:48:00 GMT 2007
VMStackWalker.getClassContext() is very fragile. This is to some
extent due to the way that _Jv_StackTrace::GetStackWalkerStack() is
written, which breaks when sibcalled.
Two fixes here. Firstly, make sure that VMStackWalker is linked: if
it isn't, none of its methods are registered in the Map used by the
unwinder. Secondly, make sure that VMStackWalker doesn't sibcall
GetStackWalkerStack(). The volatile asm I use here to prevent the
sibcall is inelegant but it's certainly effective.
Andrew.
2007-01-24 Andrew Haley <aph@redhat.com>
* gnu/classpath/natVMStackWalker.cc: Call InitClass everywhere.
(getClassContext) Add a barrier to prevent GetStackWalkerStack()
from being sibcalled.
Index: gnu/classpath/natVMStackWalker.cc
===================================================================
--- gnu/classpath/natVMStackWalker.cc (revision 121108)
+++ gnu/classpath/natVMStackWalker.cc (working copy)
@@ -17,22 +17,29 @@
#include <gnu/classpath/VMStackWalker.h>
#include <gnu/gcj/RawData.h>
#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
JArray<jclass> *
gnu::classpath::VMStackWalker::getClassContext(void)
{
- return _Jv_StackTrace::GetStackWalkerStack ();
+ _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
+ JArray<jclass> *result = _Jv_StackTrace::GetStackWalkerStack ();
+ // Prevent GetStackWalkerStack() from being sibcalled.
+ __asm__ __volatile__ ("" : : "g" (result));
+ return result;
}
jclass
gnu::classpath::VMStackWalker::getCallingClass(void)
{
+ _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
return _Jv_StackTrace::GetStackWalkerCallingClass ();
}
jclass
gnu::classpath::VMStackWalker::getCallingClass(::gnu::gcj::RawData *pc)
{
+ _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
void *f = _Unwind_FindEnclosingFunction (pc);
// FIXME: it might well be a good idea to cache pc values here in
@@ -57,12 +64,14 @@
::java::lang::ClassLoader *
gnu::classpath::VMStackWalker::getClassLoader(::java::lang::Class *c)
{
+ _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
return c->getClassLoaderInternal ();
}
::java::lang::ClassLoader *
gnu::classpath::VMStackWalker::getCallingClassLoader(void)
{
+ _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
return
_Jv_StackTrace::GetStackWalkerCallingClass ()->getClassLoaderInternal ();
}
@@ -70,11 +79,13 @@
::java::lang::ClassLoader *
gnu::classpath::VMStackWalker::getCallingClassLoader(::gnu::gcj::RawData *pc)
{
+ _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
return getCallingClass (pc)->getClassLoaderInternal ();
}
::java::lang::ClassLoader *
gnu::classpath::VMStackWalker::firstNonNullClassLoader(void)
{
+ _Jv_InitClass (&::gnu::classpath::VMStackWalker::class$);
return _Jv_StackTrace::GetStackWalkerFirstNonNullLoader ();
}
More information about the Java-patches
mailing list