This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Restore gnu.gcj.runtime.NameFinder.remove_unknown
- From: Andrew Haley <aph at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Thu, 16 Feb 2006 12:24:21 +0000
- Subject: Restore gnu.gcj.runtime.NameFinder.remove_unknown
This fixes a regression in stack traces generation whereby the system
property gnu.gcj.runtime.NameFinder.remove_unknown no longer works.
(Until it was removed, this system property allowed a user to print
all stack frames rather than just a subset that wouoldn't worry a Java
programmer.)
Why this is useful: I was debugging a very weird problem in gij when I
realized that the stack trace was misleading because so much
information had been removed.
Restoring this functionality turns this
Exception in thread "main" java.lang.NoClassDefFoundError: Foo
at java.lang.Class.initializeClass (natClass.cc:690)
at java.lang.Class.isAssignableFrom (Class.h:599)
at Test.main (Test.java:10)
Caused by: java.lang.ClassNotFoundException: javax.management.ObjectName not found in gnu.gcj.runtime.SystemClassLoader{urls=[file:./], parent=gnu.gcj.runtime.ExtensionClassLoader{urls=[], parent=null}}
at java.net.URLClassLoader.findClass (URLClassLoader.java:1080)
at java.lang.ClassLoader.loadClass (ClassLoader.java:317)
at java.lang.ClassLoader.loadClass (ClassLoader.java:260)
at java.lang.Class.forName (natClass.cc:88)
at java.lang.Class.initializeClass (natClass.cc:684)
...2 more
into
Exception in thread "main" java.lang.NoClassDefFoundError: Foo
at java.lang.Class.initializeClass (natClass.cc:690)
at java.lang.Class.isAssignableFrom (Class.h:599)
at ffi_call_unix64 (unix64.S:73)
at ffi_call (ffi64.c:428)
at ffi_java_raw_call (java_raw_api.c:295)
at Test.main (Test.java:10)
at (java_raw_api.c:309)
at ffi_closure_unix64_inner (ffi64.c:563)
at ffi_closure_unix64 (unix64.S:228)
Caused by: java.lang.ClassNotFoundException: javax.management.ObjectName not found in gnu.gcj.runtime.SystemClassLoader{urls=[file:./], parent=gnu.gcj.runtime.ExtensionClassLoader{urls=[], parent=null}}
at java.net.URLClassLoader.findClass (URLClassLoader.java:1080)
at java.lang.ClassLoader.loadClass (ClassLoader.java:317)
at java.lang.ClassLoader.loadClass (ClassLoader.java:260)
at _Jv_FindClass(_Jv_Utf8Const*, java::lang::ClassLoader*) (natClassLoader.cc:291)
at java.lang.Class.forName (natClass.cc:88)
at _Jv_BytecodeVerifier::pop_init_ref(_Jv_BytecodeVerifier::type) (verify.cc:379)
at _Jv_BytecodeVerifier::verify_instructions_0() (verify.cc:2895)
at _Jv_VerifyMethod(_Jv_InterpMethod*) (verify.cc:3090)
at _Jv_InterpreterEngine::do_verify(java::lang::Class*) (interpret.cc:3757)
at _Jv_Linker::wait_for_state(java::lang::Class*, int) (link.cc:1770)
at java.lang.Class.initializeClass (natClass.cc:684)
...8 more
and you can see at once the ClassNotFoundException in triggered by the verifier.
Andrew.
2006-02-16 Andrew Haley <aph@redhat.com>
* stacktrace.cc (GetStackTraceElements): Call
gnu::gcj::runtime::NameFinder::removeUnknown() to determine if
non-Java frames should be removed from a printed stack trace.
Pass methodName to getLineNumberForFrame().
(getLineNumberForFrame): Set method_name from info.dli_sname.
* gnu/gcj/runtime/NameFinder.java (removeUnknown): New method.
(remove_unknown): New variable.
* include/java-stack.h (_Jv_StackTrace::getLineNumberForFrame):
Add methodName arg.
Index: gnu/gcj/runtime/NameFinder.java
===================================================================
--- gnu/gcj/runtime/NameFinder.java (revision 110794)
+++ gnu/gcj/runtime/NameFinder.java (working copy)
@@ -34,6 +34,9 @@
* source file and line number info. Throwable.printStackTrace() will
* be faster if this property is set to 'false'.
* </ul>
+ * <ul><code>gnu.gcj.runtime.NameFinder.remove_unknown</code>
+ * Whether calls to unknown functions (class and method names are unknown)
+ * should be removed from the stack trace. </ul>
* </li>
*
* <code>close()</code> should be called to get rid of all resources.
@@ -57,6 +60,18 @@
("gnu.gcj.runtime.NameFinder.use_addr2line", "true")
).booleanValue();
+ private static final boolean remove_unknown
+ = Boolean.valueOf(System.getProperty
+ ("gnu.gcj.runtime.NameFinder.remove_unknown", "true")
+ ).booleanValue();
+
+ // Return true if non-Java frames should be removed from stack
+ // traces.
+ static final boolean removeUnknown()
+ {
+ return remove_unknown;
+ }
+
class Addr2Line
{
Process proc;
Index: stacktrace.cc
===================================================================
--- stacktrace.cc (revision 110794)
+++ stacktrace.cc (working copy)
@@ -171,7 +171,8 @@
void
_Jv_StackTrace::getLineNumberForFrame(_Jv_StackFrame *frame, NameFinder *finder,
- jstring *sourceFileName, jint *lineNum)
+ jstring *sourceFileName, jint *lineNum,
+ jstring *methodName)
{
#ifdef INTERPRETER
if (frame->type == frame_interpreter)
@@ -200,6 +201,9 @@
else
return;
+ if (*methodName == NULL && info.dli_sname)
+ *methodName = JvNewStringUTF (info.dli_sname);
+
// addr2line expects relative addresses for shared libraries.
if (strcmp (info.dli_fname, argv0) == 0)
offset = (_Unwind_Ptr) ip;
@@ -323,16 +327,22 @@
end_idx = i - 1;
}
+ const jboolean remove_unknown
+ = gnu::gcj::runtime::NameFinder::removeUnknown();
+
// Second pass: Look up line-number info for remaining frames.
for (int i = start_idx; i <= end_idx; i++)
{
_Jv_StackFrame *frame = &trace->frames[i];
- if (frame->klass == NULL)
- // Not a Java frame.
+ if (frame->klass == NULL && remove_unknown)
+ // Not a Java frame.
continue;
-
- jstring className = frame->klass->getName ();
+
+ jstring className = NULL;
+ if (frame->klass != NULL)
+ className = frame->klass->getName ();
+
jstring methodName = NULL;
if (frame->meth)
methodName = JvNewStringUTF (frame->meth->name->chars());
@@ -340,7 +350,8 @@
jstring sourceFileName = NULL;
jint lineNum = -1;
- getLineNumberForFrame(frame, finder, &sourceFileName, &lineNum);
+ getLineNumberForFrame(frame, finder, &sourceFileName, &lineNum,
+ &methodName);
StackTraceElement *element = new StackTraceElement (sourceFileName, lineNum,
className, methodName, 0);
Index: include/java-stack.h
===================================================================
--- include/java-stack.h (revision 110794)
+++ include/java-stack.h (working copy)
@@ -105,7 +105,8 @@
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 *sourceFileName, jint *lineNum,
+ jstring *methodName);
static _Unwind_Reason_Code UnwindTraceFn (struct _Unwind_Context *context,
void *state_ptr);