Fixes bug libgcj/8170

Fixes bug libgcj/8170
       * java/lang/ClassLoader.java (loadClass): Don't rewrap
       ClassNotFoundException.
       * gnu/java/lang/MainThread.java (run): Chain NoClassDefFoundError.
       * gnu/gcj/runtime/NameFinder.java (remove_interpreter): Removed.
       (remove_internal): New field superceding remove_interpreter.
       (sanitizeStack): Remove all no-package classes starting with "_Jv_".
       Remove no-class methods starting with "_Jv_". And Replace null
       class or method names with the empty string. Stop at either the
       MainThread or a real Thread run() method.
       (newElement): Made static.
       * java/net/URLClassLoader.java (findClass): Throw
       ClassNotFoundExceptions including urls, plus parent using toString().
       (thisString): New field.
       (toString): New method.

From-SVN: r94935
This commit is contained in:
Mark Wielaard 2005-02-12 13:51:11 +00:00 committed by Mark Wielaard
parent 8ad833acc4
commit 0008978072
5 changed files with 110 additions and 43 deletions

View File

@ -1,3 +1,21 @@
2005-02-12 Mark Wielaard <mark@klomp.org>
Fixes bug libgcj/8170
* java/lang/ClassLoader.java (loadClass): Don't rewrap
ClassNotFoundException.
* gnu/java/lang/MainThread.java (run): Chain NoClassDefFoundError.
* gnu/gcj/runtime/NameFinder.java (remove_interpreter): Removed.
(remove_internal): New field superceding remove_interpreter.
(sanitizeStack): Remove all no-package classes starting with "_Jv_".
Remove no-class methods starting with "_Jv_". And Replace null
class or method names with the empty string. Stop at either the
MainThread or a real Thread run() method.
(newElement): Made static.
* java/net/URLClassLoader.java (findClass): Throw
ClassNotFoundExceptions including urls, plus parent using toString().
(thisString): New field.
(toString): New method.
2005-02-10 Tom Tromey <tromey@redhat.com>
* external/sax/Makefile.in: Rebuilt.

View File

@ -37,8 +37,8 @@ import java.io.File;
* Whether calls to unknown functions (class and method names are unknown)
* should be removed from the stack trace. Only done when the stack is
* sanitized.</ul>
* <ul><code>gnu.gcj.runtime.NameFinder.remove_interpreter</code>
* Whether runtime interpreter calls (methods in the _Jv_InterpMethod class
* <ul><code>gnu.gcj.runtime.NameFinder.remove_internal</code>
* Whether runtime internal calls (methods in the internal _Jv_* classes
* and functions starting with 'ffi_') should be removed from the stack
* trace. Only done when the stack is sanitized.</ul>
* <ul><code>gnu.gcj.runtime.NameFinder.use_addr2line</code>
@ -72,10 +72,18 @@ public class NameFinder
= Boolean.valueOf(System.getProperty
("gnu.gcj.runtime.NameFinder.remove_unknown", "true")
).booleanValue();
private static final boolean remove_interpreter
= Boolean.valueOf(System.getProperty
// The remove_interpreter name is an old 3.3/3.4 (deprecated) synonym.
private static final boolean remove_internal
= (Boolean.valueOf(System.getProperty
("gnu.gcj.runtime.NameFinder.remove_internal", "true")
).booleanValue()
||
Boolean.valueOf(System.getProperty
("gnu.gcj.runtime.NameFinder.remove_interpreter", "true")
).booleanValue();
).booleanValue()
);
private static final boolean use_addr2line
= Boolean.valueOf(System.getProperty
("gnu.gcj.runtime.NameFinder.use_addr2line", "true")
@ -280,7 +288,7 @@ public class NameFinder
consName = className.substring(lastDot + 1) + '(';
int unknown = 0;
int interpreter = 0;
int internal = 0;
int last_throw = -1;
int length = elements.length;
int end = length-1;
@ -300,19 +308,23 @@ public class NameFinder
|| MName.startsWith("fillInStackTrace("))))
{
last_throw = i;
// Reset counting of unknown and interpreter frames.
// Reset counting of unknown and internal frames.
unknown = 0;
interpreter = 0;
internal = 0;
}
else if (remove_unknown && CName == null
&& (MName == null || MName.startsWith("0x")))
unknown++;
else if (remove_interpreter
else if (remove_internal
&& ((CName == null
&& MName != null && MName.startsWith("ffi_"))
|| (CName != null && CName.equals("_Jv_InterpMethod"))))
interpreter++;
else if ("main(java.lang.String[])".equals(MName))
|| (CName != null && CName.startsWith("_Jv_"))
|| (CName == null && MName != null
&& MName.startsWith("_Jv_"))))
internal++;
else if (("java.lang.Thread".equals(CName)
|| "gnu.java.lang.MainThread".equals(CName))
&& "run()".equals(MName))
{
end = i;
break;
@ -321,11 +333,11 @@ public class NameFinder
int begin = last_throw+1;
// Now filter out everything at the start and the end that is not part
// of the "normal" user program including any elements that are interpreter
// of the "normal" user program including any elements that are internal
// calls or have no usefull information whatsoever.
// Unless that means we filter out all info.
int nr_elements = end-begin-unknown-interpreter+1;
if ((begin > 0 || end < length-1 || unknown > 0 || interpreter > 0)
int nr_elements = end - begin - unknown - internal + 1;
if ((begin > 0 || end < length-1 || unknown > 0 || internal > 0)
&& nr_elements > 0)
{
stack = new StackTraceElement[nr_elements];
@ -337,14 +349,27 @@ public class NameFinder
if (remove_unknown && CName == null
&& (MName == null || MName.startsWith("0x")))
; // Skip unknown frame
else if (remove_interpreter
else if (remove_internal
&& ((CName == null
&& MName != null && MName.startsWith("ffi_"))
|| (CName != null && CName.equals("_Jv_InterpMethod"))))
; // Skip interpreter runtime frame
&& MName != null && MName.startsWith("ffi_"))
|| (CName != null && CName.startsWith("_Jv_"))
|| (CName == null && MName != null
&& MName.startsWith("_Jv_"))))
; // Skip internal runtime frame
else
{
stack[pos] = elements[i];
// Null Class or Method name in elements are not allowed.
if (MName == null || CName == null)
{
MName = MName == null ? "" : MName;
CName = CName == null ? "" : CName;
stack[pos] = newElement(elements[i].getFileName(),
elements[i].getLineNumber(),
CName, MName,
elements[i].isNativeMethod());
}
else
stack[pos] = elements[i];
pos++;
}
}
@ -359,11 +384,11 @@ public class NameFinder
* Native helper method to create a StackTraceElement. Needed to work
* around normal Java access restrictions.
*/
native private StackTraceElement newElement(String fileName,
int lineNumber,
String className,
String methName,
boolean isNative);
native static private StackTraceElement newElement(String fileName,
int lineNumber,
String className,
String methName,
boolean isNative);
/**
* Creates a StackTraceElement given a string and a filename.

View File

@ -95,7 +95,9 @@ final class MainThread extends Thread
}
catch (ClassNotFoundException x)
{
throw new NoClassDefFoundError(klass_name);
NoClassDefFoundError ncdfe = new NoClassDefFoundError(klass_name);
ncdfe.initCause(x);
throw ncdfe;
}
}

View File

@ -288,8 +288,6 @@ public abstract class ClassLoader
if (c != null)
return c;
ClassNotFoundException ex = null;
// Can the class be loaded by a parent?
try
{
@ -306,20 +304,9 @@ public abstract class ClassLoader
}
catch (ClassNotFoundException e)
{
ex = e;
}
// Still not found, we have to do it ourself.
try
{
c = findClass(name);
}
catch (ClassNotFoundException cause)
{
if (ex != null)
throw new ClassNotFoundException(ex.toString(), cause);
else
throw cause;
}
c = findClass(name);
if (resolve)
resolveClass(c);
return c;

View File

@ -1,5 +1,6 @@
/* URLClassLoader.java -- ClassLoader that loads classes from one or more URLs
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -958,7 +959,7 @@ public class URLClassLoader extends SecureClassLoader
resource = loader.getResource(resourceName);
}
if (resource == null)
throw new ClassNotFoundException(className + " not found in " + urls);
throw new ClassNotFoundException(className + " not found in " + this);
// Try to read the class data, create the CodeSource, Package and
// construct the class (and watch out for those nasty IOExceptions)
@ -1039,9 +1040,43 @@ public class URLClassLoader extends SecureClassLoader
}
catch (IOException ioe)
{
throw new ClassNotFoundException(className, ioe);
ClassNotFoundException cnfe;
cnfe = new ClassNotFoundException(className + " not found in " + this);
cnfe.initCause(ioe);
throw cnfe;
}
}
// Cached String representation of this URLClassLoader
private String thisString;
/**
* Returns a String representation of this URLClassLoader giving the
* actual Class name, the URLs that are searched and the parent
* ClassLoader.
*/
public String toString()
{
if (thisString == null)
{
StringBuffer sb = new StringBuffer();
sb.append(this.getClass().getName());
sb.append("{urls=[" );
URL[] thisURLs = getURLs();
for (int i = 0; i < thisURLs.length; i++)
{
sb.append(thisURLs[i]);
if (i < thisURLs.length - 1)
sb.append(',');
}
sb.append(']');
sb.append(", parent=");
sb.append(getParent());
sb.append('}');
thisString = sb.toString();
}
return thisString;
}
/**
* Finds the first occurrence of a resource that can be found. The locations