This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]