This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] java stacktrace fix
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org, java-patches at gcc dot gnu dot org
- Date: Wed, 31 May 2006 00:05:37 +0930
- Subject: [PATCH] java stacktrace fix
This patch fixes a bug responsible for failure of the new
libjava.lang/stacktrace.java test on powerpc64-linux, which was giving
output like the following:
stacktrace.main
stacktrace.e
stacktrace.main
stacktrace.d
stacktrace.main
stacktrace.c
stacktrace.main
stacktrace.b
stacktrace.main
stacktrace.a
stacktrace.main
stacktrace.main
stacktrace.main
PASS: stacktrace execution - gij test
FAIL: stacktrace output - gij test
After much head head-scratching I finally tracked this down to
interpreted class methods being added to ncodeMap. On architectures
where UNWRAP_FUNCTION_DESCRIPTOR is a no-op this doesn't hurt too much.
The addresses incorrectly added to ncodeMap are just those of blocks of
malloc'd memory (see interpret.cc _Jv_InterpMethod::ncode), which won't
match any code address found in a backtrace. However on powerpc64 we
dereference that malloc'd memory, and it so happens that we have a copy
of a function descriptor there (see libffi/src/powerpc/ffi.c
ffi_prep_closure). The net result is that ffi_closure_LINUX64
incorrectly appears in the stack backtrace as if it were a method.
This would all have been found much quicker if JvAssert actually did
something on my default builds..
* stacktrace.cc (_Jv_StackTrace::UpdateNCodeMap): Don't add
interpreted classes.
Bootstrapped and regression tested powerpc64-linux. OK mainline?
Index: libjava/stacktrace.cc
===================================================================
--- libjava/stacktrace.cc (revision 114231)
+++ libjava/stacktrace.cc (working copy)
@@ -55,23 +55,25 @@ _Jv_StackTrace::UpdateNCodeMap ()
jclass klass;
while ((klass = _Jv_PopClass ()))
- {
- //printf ("got %s\n", klass->name->data);
+ if (1
#ifdef INTERPRETER
- JvAssert (! _Jv_IsInterpretedClass (klass));
+ && !_Jv_IsInterpretedClass (klass)
#endif
- 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);
- }
- }
- }
+ )
+ {
+ //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
--
Alan Modra
IBM OzLabs - Linux Technology Centre