mirror of git://gcc.gnu.org/git/gcc.git
Makefile.am (libgcj_la_SOURCES): Remove name-finder.cc.
* Makefile.am (libgcj_la_SOURCES): Remove name-finder.cc.
(core_java_source_files): Add VMThrowable.java and NameFinder.java
(nat_source_files): Remove natThrowable.cc, add natVMThrowable.cc
and natNameFinder.cc.
* Makefile.in: Regenerate.
* prims.cc: Use trace_enabled from VMThrowable.
* name-finder.cc: Removed.
* gcj/javaprims.h: Add class VMThrowable.
* gnu/gcj/runtime/NameFinder.java: New file.
* gnu/gcj/runtime/natNameFinder.cc: Likewise.
* include/name-finder.h: Removed.
* java/lang/Throwable.java (printStackTrace (PrintStream)): Use new
method stackTraceString().
(printStackTrace (PrintWriter)): Likewise.
(stackTraceString): Complete rewrite of old printStackTrace using
StringBuffer.
(stackTraceStringBuffer): New helper method for stackTraceString().
(fillInStackTrace): Delegate to VMTrowable.
(getStackTrace): Likewise.
(getStackTrace0): Removed.
(trace_enabled, stackTraceBytes): Moved to new VMThrowable.java.
(setStackTrace): Copy given array.
* java/lang/natThrowable.cc: Removed (replaced by natVMThrowable).
* java/lang/VMThrowable.java: New class.
* java/lang/natVMThrowable.cc: New file.
From-SVN: r56556
This commit is contained in:
parent
4906d5d83e
commit
6e0532cdf6
|
|
@ -1,3 +1,31 @@
|
||||||
|
2002-08-24 Mark Wielaard <mark@klomp.org>
|
||||||
|
|
||||||
|
* Makefile.am (libgcj_la_SOURCES): Remove name-finder.cc.
|
||||||
|
(core_java_source_files): Add VMThrowable.java and NameFinder.java
|
||||||
|
(nat_source_files): Remove natThrowable.cc, add natVMThrowable.cc
|
||||||
|
and natNameFinder.cc.
|
||||||
|
* Makefile.in: Regenerate.
|
||||||
|
* prims.cc: Use trace_enabled from VMThrowable.
|
||||||
|
* name-finder.cc: Removed.
|
||||||
|
* gcj/javaprims.h: Add class VMThrowable.
|
||||||
|
* gnu/gcj/runtime/NameFinder.java: New file.
|
||||||
|
* gnu/gcj/runtime/natNameFinder.cc: Likewise.
|
||||||
|
* include/name-finder.h: Removed.
|
||||||
|
* java/lang/Throwable.java (printStackTrace (PrintStream)): Use new
|
||||||
|
method stackTraceString().
|
||||||
|
(printStackTrace (PrintWriter)): Likewise.
|
||||||
|
(stackTraceString): Complete rewrite of old printStackTrace using
|
||||||
|
StringBuffer.
|
||||||
|
(stackTraceStringBuffer): New helper method for stackTraceString().
|
||||||
|
(fillInStackTrace): Delegate to VMTrowable.
|
||||||
|
(getStackTrace): Likewise.
|
||||||
|
(getStackTrace0): Removed.
|
||||||
|
(trace_enabled, stackTraceBytes): Moved to new VMThrowable.java.
|
||||||
|
(setStackTrace): Copy given array.
|
||||||
|
* java/lang/natThrowable.cc: Removed (replaced by natVMThrowable).
|
||||||
|
* java/lang/VMThrowable.java: New class.
|
||||||
|
* java/lang/natVMThrowable.cc: New file.
|
||||||
|
|
||||||
2003-08-23 Michael Koch <konqueror@gmx.de>
|
2003-08-23 Michael Koch <konqueror@gmx.de>
|
||||||
|
|
||||||
* java/net/URLConnection.java,
|
* java/net/URLConnection.java,
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ javao_files = $(java_source_files:.java=.lo) \
|
||||||
x_javao_files = $(x_java_source_files:.java=.lo)
|
x_javao_files = $(x_java_source_files:.java=.lo)
|
||||||
|
|
||||||
libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
|
libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
|
||||||
resolve.cc defineclass.cc interpret.cc name-finder.cc verify.cc \
|
resolve.cc defineclass.cc interpret.cc verify.cc \
|
||||||
$(nat_source_files)
|
$(nat_source_files)
|
||||||
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
|
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
|
||||||
win32-threads.cc posix.cc win32.cc \
|
win32-threads.cc posix.cc win32.cc \
|
||||||
|
|
@ -1527,6 +1527,7 @@ java/lang/VerifyError.java \
|
||||||
java/lang/VirtualMachineError.java \
|
java/lang/VirtualMachineError.java \
|
||||||
java/lang/VMClassLoader.java \
|
java/lang/VMClassLoader.java \
|
||||||
java/lang/VMSecurityManager.java \
|
java/lang/VMSecurityManager.java \
|
||||||
|
java/lang/VMThrowable.java \
|
||||||
java/lang/Void.java \
|
java/lang/Void.java \
|
||||||
java/io/BufferedInputStream.java \
|
java/io/BufferedInputStream.java \
|
||||||
java/io/BufferedOutputStream.java \
|
java/io/BufferedOutputStream.java \
|
||||||
|
|
@ -1687,6 +1688,7 @@ gnu/gcj/runtime/FileDeleter.java \
|
||||||
gnu/gcj/runtime/FinalizerThread.java \
|
gnu/gcj/runtime/FinalizerThread.java \
|
||||||
gnu/gcj/runtime/FirstThread.java \
|
gnu/gcj/runtime/FirstThread.java \
|
||||||
gnu/gcj/runtime/JNIWeakRef.java \
|
gnu/gcj/runtime/JNIWeakRef.java \
|
||||||
|
gnu/gcj/runtime/NameFinder.java \
|
||||||
gnu/gcj/runtime/SharedLibLoader.java \
|
gnu/gcj/runtime/SharedLibLoader.java \
|
||||||
gnu/gcj/runtime/StringBuffer.java \
|
gnu/gcj/runtime/StringBuffer.java \
|
||||||
gnu/gcj/runtime/VMClassLoader.java \
|
gnu/gcj/runtime/VMClassLoader.java \
|
||||||
|
|
@ -2204,6 +2206,7 @@ gnu/gcj/io/shs.cc \
|
||||||
gnu/gcj/protocol/core/natCoreInputStream.cc \
|
gnu/gcj/protocol/core/natCoreInputStream.cc \
|
||||||
gnu/gcj/runtime/natFinalizerThread.cc \
|
gnu/gcj/runtime/natFinalizerThread.cc \
|
||||||
gnu/gcj/runtime/natFirstThread.cc \
|
gnu/gcj/runtime/natFirstThread.cc \
|
||||||
|
gnu/gcj/runtime/natNameFinder.cc \
|
||||||
gnu/gcj/runtime/natSharedLibLoader.cc \
|
gnu/gcj/runtime/natSharedLibLoader.cc \
|
||||||
gnu/gcj/runtime/natStringBuffer.cc \
|
gnu/gcj/runtime/natStringBuffer.cc \
|
||||||
java/io/natFile.cc \
|
java/io/natFile.cc \
|
||||||
|
|
@ -2223,7 +2226,7 @@ java/lang/natString.cc \
|
||||||
java/lang/natStringBuffer.cc \
|
java/lang/natStringBuffer.cc \
|
||||||
java/lang/natSystem.cc \
|
java/lang/natSystem.cc \
|
||||||
java/lang/natThread.cc \
|
java/lang/natThread.cc \
|
||||||
java/lang/natThrowable.cc \
|
java/lang/natVMThrowable.cc \
|
||||||
java/lang/ref/natReference.cc \
|
java/lang/ref/natReference.cc \
|
||||||
java/lang/reflect/natArray.cc \
|
java/lang/reflect/natArray.cc \
|
||||||
java/lang/reflect/natConstructor.cc \
|
java/lang/reflect/natConstructor.cc \
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ javao_files = $(java_source_files:.java=.lo) \
|
||||||
x_javao_files = $(x_java_source_files:.java=.lo)
|
x_javao_files = $(x_java_source_files:.java=.lo)
|
||||||
|
|
||||||
libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
|
libgcj_la_SOURCES = prims.cc jni.cc exception.cc \
|
||||||
resolve.cc defineclass.cc interpret.cc name-finder.cc verify.cc \
|
resolve.cc defineclass.cc interpret.cc verify.cc \
|
||||||
$(nat_source_files)
|
$(nat_source_files)
|
||||||
|
|
||||||
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
|
EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \
|
||||||
|
|
@ -1294,6 +1294,7 @@ java/lang/VerifyError.java \
|
||||||
java/lang/VirtualMachineError.java \
|
java/lang/VirtualMachineError.java \
|
||||||
java/lang/VMClassLoader.java \
|
java/lang/VMClassLoader.java \
|
||||||
java/lang/VMSecurityManager.java \
|
java/lang/VMSecurityManager.java \
|
||||||
|
java/lang/VMThrowable.java \
|
||||||
java/lang/Void.java \
|
java/lang/Void.java \
|
||||||
java/io/BufferedInputStream.java \
|
java/io/BufferedInputStream.java \
|
||||||
java/io/BufferedOutputStream.java \
|
java/io/BufferedOutputStream.java \
|
||||||
|
|
@ -1449,6 +1450,7 @@ gnu/gcj/runtime/FileDeleter.java \
|
||||||
gnu/gcj/runtime/FinalizerThread.java \
|
gnu/gcj/runtime/FinalizerThread.java \
|
||||||
gnu/gcj/runtime/FirstThread.java \
|
gnu/gcj/runtime/FirstThread.java \
|
||||||
gnu/gcj/runtime/JNIWeakRef.java \
|
gnu/gcj/runtime/JNIWeakRef.java \
|
||||||
|
gnu/gcj/runtime/NameFinder.java \
|
||||||
gnu/gcj/runtime/SharedLibLoader.java \
|
gnu/gcj/runtime/SharedLibLoader.java \
|
||||||
gnu/gcj/runtime/StringBuffer.java \
|
gnu/gcj/runtime/StringBuffer.java \
|
||||||
gnu/gcj/runtime/VMClassLoader.java \
|
gnu/gcj/runtime/VMClassLoader.java \
|
||||||
|
|
@ -1965,6 +1967,7 @@ gnu/gcj/io/shs.cc \
|
||||||
gnu/gcj/protocol/core/natCoreInputStream.cc \
|
gnu/gcj/protocol/core/natCoreInputStream.cc \
|
||||||
gnu/gcj/runtime/natFinalizerThread.cc \
|
gnu/gcj/runtime/natFinalizerThread.cc \
|
||||||
gnu/gcj/runtime/natFirstThread.cc \
|
gnu/gcj/runtime/natFirstThread.cc \
|
||||||
|
gnu/gcj/runtime/natNameFinder.cc \
|
||||||
gnu/gcj/runtime/natSharedLibLoader.cc \
|
gnu/gcj/runtime/natSharedLibLoader.cc \
|
||||||
gnu/gcj/runtime/natStringBuffer.cc \
|
gnu/gcj/runtime/natStringBuffer.cc \
|
||||||
java/io/natFile.cc \
|
java/io/natFile.cc \
|
||||||
|
|
@ -1984,7 +1987,7 @@ java/lang/natString.cc \
|
||||||
java/lang/natStringBuffer.cc \
|
java/lang/natStringBuffer.cc \
|
||||||
java/lang/natSystem.cc \
|
java/lang/natSystem.cc \
|
||||||
java/lang/natThread.cc \
|
java/lang/natThread.cc \
|
||||||
java/lang/natThrowable.cc \
|
java/lang/natVMThrowable.cc \
|
||||||
java/lang/ref/natReference.cc \
|
java/lang/ref/natReference.cc \
|
||||||
java/lang/reflect/natArray.cc \
|
java/lang/reflect/natArray.cc \
|
||||||
java/lang/reflect/natConstructor.cc \
|
java/lang/reflect/natConstructor.cc \
|
||||||
|
|
@ -2123,7 +2126,7 @@ X_LIBS = @X_LIBS@
|
||||||
X_EXTRA_LIBS = @X_EXTRA_LIBS@
|
X_EXTRA_LIBS = @X_EXTRA_LIBS@
|
||||||
X_PRE_LIBS = @X_PRE_LIBS@
|
X_PRE_LIBS = @X_PRE_LIBS@
|
||||||
libgcj_la_OBJECTS = prims.lo jni.lo exception.lo resolve.lo \
|
libgcj_la_OBJECTS = prims.lo jni.lo exception.lo resolve.lo \
|
||||||
defineclass.lo interpret.lo name-finder.lo verify.lo gnu/gcj/natCore.lo \
|
defineclass.lo interpret.lo verify.lo gnu/gcj/natCore.lo \
|
||||||
gnu/gcj/convert/JIS0208_to_Unicode.lo \
|
gnu/gcj/convert/JIS0208_to_Unicode.lo \
|
||||||
gnu/gcj/convert/JIS0212_to_Unicode.lo gnu/gcj/convert/Unicode_to_JIS.lo \
|
gnu/gcj/convert/JIS0212_to_Unicode.lo gnu/gcj/convert/Unicode_to_JIS.lo \
|
||||||
gnu/gcj/convert/natIconv.lo gnu/gcj/convert/natInput_EUCJIS.lo \
|
gnu/gcj/convert/natIconv.lo gnu/gcj/convert/natInput_EUCJIS.lo \
|
||||||
|
|
@ -2131,7 +2134,7 @@ gnu/gcj/convert/natInput_SJIS.lo gnu/gcj/convert/natOutput_EUCJIS.lo \
|
||||||
gnu/gcj/convert/natOutput_SJIS.lo gnu/gcj/io/natSimpleSHSStream.lo \
|
gnu/gcj/convert/natOutput_SJIS.lo gnu/gcj/io/natSimpleSHSStream.lo \
|
||||||
gnu/gcj/io/shs.lo gnu/gcj/protocol/core/natCoreInputStream.lo \
|
gnu/gcj/io/shs.lo gnu/gcj/protocol/core/natCoreInputStream.lo \
|
||||||
gnu/gcj/runtime/natFinalizerThread.lo gnu/gcj/runtime/natFirstThread.lo \
|
gnu/gcj/runtime/natFinalizerThread.lo gnu/gcj/runtime/natFirstThread.lo \
|
||||||
gnu/gcj/runtime/natSharedLibLoader.lo \
|
gnu/gcj/runtime/natNameFinder.lo gnu/gcj/runtime/natSharedLibLoader.lo \
|
||||||
gnu/gcj/runtime/natStringBuffer.lo java/io/natFile.lo \
|
gnu/gcj/runtime/natStringBuffer.lo java/io/natFile.lo \
|
||||||
java/io/natFileDescriptor.lo java/io/natObjectInputStream.lo \
|
java/io/natFileDescriptor.lo java/io/natObjectInputStream.lo \
|
||||||
java/io/natObjectOutputStream.lo java/lang/natCharacter.lo \
|
java/io/natObjectOutputStream.lo java/lang/natCharacter.lo \
|
||||||
|
|
@ -2140,7 +2143,7 @@ java/lang/natConcreteProcess.lo java/lang/natDouble.lo \
|
||||||
java/lang/natFloat.lo java/lang/natMath.lo java/lang/natObject.lo \
|
java/lang/natFloat.lo java/lang/natMath.lo java/lang/natObject.lo \
|
||||||
java/lang/natRuntime.lo java/lang/natString.lo \
|
java/lang/natRuntime.lo java/lang/natString.lo \
|
||||||
java/lang/natStringBuffer.lo java/lang/natSystem.lo \
|
java/lang/natStringBuffer.lo java/lang/natSystem.lo \
|
||||||
java/lang/natThread.lo java/lang/natThrowable.lo \
|
java/lang/natThread.lo java/lang/natVMThrowable.lo \
|
||||||
java/lang/ref/natReference.lo java/lang/reflect/natArray.lo \
|
java/lang/ref/natReference.lo java/lang/reflect/natArray.lo \
|
||||||
java/lang/reflect/natConstructor.lo java/lang/reflect/natField.lo \
|
java/lang/reflect/natConstructor.lo java/lang/reflect/natField.lo \
|
||||||
java/lang/reflect/natMethod.lo java/net/natInetAddress.lo \
|
java/lang/reflect/natMethod.lo java/net/natInetAddress.lo \
|
||||||
|
|
@ -2246,11 +2249,13 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||||
.deps/gnu/gcj/runtime/FileDeleter.P \
|
.deps/gnu/gcj/runtime/FileDeleter.P \
|
||||||
.deps/gnu/gcj/runtime/FinalizerThread.P \
|
.deps/gnu/gcj/runtime/FinalizerThread.P \
|
||||||
.deps/gnu/gcj/runtime/FirstThread.P .deps/gnu/gcj/runtime/JNIWeakRef.P \
|
.deps/gnu/gcj/runtime/FirstThread.P .deps/gnu/gcj/runtime/JNIWeakRef.P \
|
||||||
|
.deps/gnu/gcj/runtime/NameFinder.P \
|
||||||
.deps/gnu/gcj/runtime/SharedLibLoader.P \
|
.deps/gnu/gcj/runtime/SharedLibLoader.P \
|
||||||
.deps/gnu/gcj/runtime/StringBuffer.P \
|
.deps/gnu/gcj/runtime/StringBuffer.P \
|
||||||
.deps/gnu/gcj/runtime/VMClassLoader.P \
|
.deps/gnu/gcj/runtime/VMClassLoader.P \
|
||||||
.deps/gnu/gcj/runtime/natFinalizerThread.P \
|
.deps/gnu/gcj/runtime/natFinalizerThread.P \
|
||||||
.deps/gnu/gcj/runtime/natFirstThread.P \
|
.deps/gnu/gcj/runtime/natFirstThread.P \
|
||||||
|
.deps/gnu/gcj/runtime/natNameFinder.P \
|
||||||
.deps/gnu/gcj/runtime/natSharedLibLoader.P \
|
.deps/gnu/gcj/runtime/natSharedLibLoader.P \
|
||||||
.deps/gnu/gcj/runtime/natStringBuffer.P .deps/gnu/gcj/xlib/Clip.P \
|
.deps/gnu/gcj/runtime/natStringBuffer.P .deps/gnu/gcj/xlib/Clip.P \
|
||||||
.deps/gnu/gcj/xlib/Colormap.P .deps/gnu/gcj/xlib/Display.P \
|
.deps/gnu/gcj/xlib/Colormap.P .deps/gnu/gcj/xlib/Display.P \
|
||||||
|
|
@ -2813,8 +2818,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||||
.deps/java/lang/UnsupportedClassVersionError.P \
|
.deps/java/lang/UnsupportedClassVersionError.P \
|
||||||
.deps/java/lang/UnsupportedOperationException.P \
|
.deps/java/lang/UnsupportedOperationException.P \
|
||||||
.deps/java/lang/VMClassLoader.P .deps/java/lang/VMSecurityManager.P \
|
.deps/java/lang/VMClassLoader.P .deps/java/lang/VMSecurityManager.P \
|
||||||
.deps/java/lang/VerifyError.P .deps/java/lang/VirtualMachineError.P \
|
.deps/java/lang/VMThrowable.P .deps/java/lang/VerifyError.P \
|
||||||
.deps/java/lang/Void.P .deps/java/lang/dtoa.P .deps/java/lang/e_acos.P \
|
.deps/java/lang/VirtualMachineError.P .deps/java/lang/Void.P \
|
||||||
|
.deps/java/lang/dtoa.P .deps/java/lang/e_acos.P \
|
||||||
.deps/java/lang/e_asin.P .deps/java/lang/e_atan2.P \
|
.deps/java/lang/e_asin.P .deps/java/lang/e_atan2.P \
|
||||||
.deps/java/lang/e_exp.P .deps/java/lang/e_fmod.P \
|
.deps/java/lang/e_exp.P .deps/java/lang/e_fmod.P \
|
||||||
.deps/java/lang/e_log.P .deps/java/lang/e_pow.P \
|
.deps/java/lang/e_log.P .deps/java/lang/e_pow.P \
|
||||||
|
|
@ -2828,7 +2834,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||||
.deps/java/lang/natMath.P .deps/java/lang/natObject.P \
|
.deps/java/lang/natMath.P .deps/java/lang/natObject.P \
|
||||||
.deps/java/lang/natRuntime.P .deps/java/lang/natString.P \
|
.deps/java/lang/natRuntime.P .deps/java/lang/natString.P \
|
||||||
.deps/java/lang/natStringBuffer.P .deps/java/lang/natSystem.P \
|
.deps/java/lang/natStringBuffer.P .deps/java/lang/natSystem.P \
|
||||||
.deps/java/lang/natThread.P .deps/java/lang/natThrowable.P \
|
.deps/java/lang/natThread.P .deps/java/lang/natVMThrowable.P \
|
||||||
.deps/java/lang/ref/PhantomReference.P .deps/java/lang/ref/Reference.P \
|
.deps/java/lang/ref/PhantomReference.P .deps/java/lang/ref/Reference.P \
|
||||||
.deps/java/lang/ref/ReferenceQueue.P \
|
.deps/java/lang/ref/ReferenceQueue.P \
|
||||||
.deps/java/lang/ref/SoftReference.P .deps/java/lang/ref/WeakReference.P \
|
.deps/java/lang/ref/SoftReference.P .deps/java/lang/ref/WeakReference.P \
|
||||||
|
|
@ -3468,17 +3474,17 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||||
.deps/javax/transaction/UserTransaction.P \
|
.deps/javax/transaction/UserTransaction.P \
|
||||||
.deps/javax/transaction/xa/XAException.P \
|
.deps/javax/transaction/xa/XAException.P \
|
||||||
.deps/javax/transaction/xa/XAResource.P \
|
.deps/javax/transaction/xa/XAResource.P \
|
||||||
.deps/javax/transaction/xa/Xid.P .deps/jni.P .deps/name-finder.P \
|
.deps/javax/transaction/xa/Xid.P .deps/jni.P .deps/no-threads.P \
|
||||||
.deps/no-threads.P .deps/nogc.P .deps/org/w3c/dom/Attr.P \
|
.deps/nogc.P .deps/org/w3c/dom/Attr.P .deps/org/w3c/dom/CDATASection.P \
|
||||||
.deps/org/w3c/dom/CDATASection.P .deps/org/w3c/dom/CharacterData.P \
|
.deps/org/w3c/dom/CharacterData.P .deps/org/w3c/dom/Comment.P \
|
||||||
.deps/org/w3c/dom/Comment.P .deps/org/w3c/dom/DOMException.P \
|
.deps/org/w3c/dom/DOMException.P .deps/org/w3c/dom/DOMImplementation.P \
|
||||||
.deps/org/w3c/dom/DOMImplementation.P .deps/org/w3c/dom/Document.P \
|
.deps/org/w3c/dom/Document.P .deps/org/w3c/dom/DocumentFragment.P \
|
||||||
.deps/org/w3c/dom/DocumentFragment.P .deps/org/w3c/dom/DocumentType.P \
|
.deps/org/w3c/dom/DocumentType.P .deps/org/w3c/dom/Element.P \
|
||||||
.deps/org/w3c/dom/Element.P .deps/org/w3c/dom/Entity.P \
|
.deps/org/w3c/dom/Entity.P .deps/org/w3c/dom/EntityReference.P \
|
||||||
.deps/org/w3c/dom/EntityReference.P .deps/org/w3c/dom/NamedNodeMap.P \
|
.deps/org/w3c/dom/NamedNodeMap.P .deps/org/w3c/dom/Node.P \
|
||||||
.deps/org/w3c/dom/Node.P .deps/org/w3c/dom/NodeList.P \
|
.deps/org/w3c/dom/NodeList.P .deps/org/w3c/dom/Notation.P \
|
||||||
.deps/org/w3c/dom/Notation.P .deps/org/w3c/dom/ProcessingInstruction.P \
|
.deps/org/w3c/dom/ProcessingInstruction.P .deps/org/w3c/dom/Text.P \
|
||||||
.deps/org/w3c/dom/Text.P .deps/org/w3c/dom/ranges/DocumentRange.P \
|
.deps/org/w3c/dom/ranges/DocumentRange.P \
|
||||||
.deps/org/w3c/dom/ranges/Range.P \
|
.deps/org/w3c/dom/ranges/Range.P \
|
||||||
.deps/org/w3c/dom/ranges/RangeException.P \
|
.deps/org/w3c/dom/ranges/RangeException.P \
|
||||||
.deps/org/w3c/dom/traversal/DocumentTraversal.P \
|
.deps/org/w3c/dom/traversal/DocumentTraversal.P \
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,7 @@ extern "Java"
|
||||||
class UnsupportedOperationException;
|
class UnsupportedOperationException;
|
||||||
class VMClassLoader;
|
class VMClassLoader;
|
||||||
class VMSecurityManager;
|
class VMSecurityManager;
|
||||||
|
class VMThrowable;
|
||||||
class VerifyError;
|
class VerifyError;
|
||||||
class VirtualMachineError;
|
class VirtualMachineError;
|
||||||
class Void;
|
class Void;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,407 @@
|
||||||
|
/* NameFinder.java -- Translates addresses to StackTraceElements.
|
||||||
|
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
This software is copyrighted work licensed under the terms of the
|
||||||
|
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
package gnu.gcj.runtime;
|
||||||
|
|
||||||
|
import gnu.gcj.RawData;
|
||||||
|
|
||||||
|
import java.lang.StringBuffer;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that translates addresses (represented as longs) to a
|
||||||
|
* StackTraceElement array.
|
||||||
|
*
|
||||||
|
* There are a couple of system properties that can be set to manipulate the
|
||||||
|
* result (all default to true):
|
||||||
|
* <li>
|
||||||
|
* <ul><code>gnu.gcj.runtime.NameFinder.demangle</code>
|
||||||
|
* Whether names should be demangled.</ul>
|
||||||
|
* <ul><code>gnu.gcj.runtime.NameFinder.sanitize</code></ul>
|
||||||
|
* Whether calls to initialize exceptions and starting the runtime system
|
||||||
|
* should be removed from the stack trace. Only done when names are
|
||||||
|
* demangled.</ul>
|
||||||
|
* <ul><code>gnu.gcj.runtime.NameFinder.remove_unknown</code>
|
||||||
|
* Wheter 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.use_addr2line</code>
|
||||||
|
* Wheter an external process (addr2line or addr2name.awk) should be used
|
||||||
|
* as fallback to convert the addresses to function names when the runtime
|
||||||
|
* is unable to do it through <code>dladdr</code>.</ul>
|
||||||
|
* </li>
|
||||||
|
*
|
||||||
|
* <code>close()</code> should be called to get rid of all resources.
|
||||||
|
*
|
||||||
|
* This class is used from <code>java.lang.VMThrowable</code>.
|
||||||
|
*
|
||||||
|
* Currently the <code>lookup(long[])</code> method is not thread safe.
|
||||||
|
* It can easily be made thread safe by synchronizing access to all external
|
||||||
|
* processes when used.
|
||||||
|
*
|
||||||
|
* @author Mark Wielaard (mark@klomp.org)
|
||||||
|
*/
|
||||||
|
public class NameFinder
|
||||||
|
{
|
||||||
|
// Set these to false when not needed.
|
||||||
|
private static final boolean demangle
|
||||||
|
= Boolean.valueOf(System.getProperty
|
||||||
|
("gnu.gcj.runtime.NameFinder.demangle", "true")
|
||||||
|
).booleanValue();
|
||||||
|
private static final boolean sanitize
|
||||||
|
= Boolean.valueOf(System.getProperty
|
||||||
|
("gnu.gcj.runtime.NameFinder.sanitize", "true")
|
||||||
|
).booleanValue();
|
||||||
|
private static final boolean remove_unknown
|
||||||
|
= Boolean.valueOf(System.getProperty
|
||||||
|
("gnu.gcj.runtime.NameFinder.remove_unknown", "true")
|
||||||
|
).booleanValue();
|
||||||
|
private static final boolean use_addr2line
|
||||||
|
= Boolean.valueOf(System.getProperty
|
||||||
|
("gnu.gcj.runtime.NameFinder.use_addr2line", "true")
|
||||||
|
).booleanValue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the currently running executable.
|
||||||
|
*/
|
||||||
|
private final String executable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process used for demangling names.
|
||||||
|
*/
|
||||||
|
private Process cppfilt;
|
||||||
|
|
||||||
|
private BufferedWriter cppfiltOut;
|
||||||
|
private BufferedReader cppfiltIn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process used for translating addresses to function/file names.
|
||||||
|
*/
|
||||||
|
private Process addr2line;
|
||||||
|
|
||||||
|
private BufferedWriter addr2lineOut;
|
||||||
|
private BufferedReader addr2lineIn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new NameFinder. Call close to get rid of any resources
|
||||||
|
* created while using the <code>lookup</code> methods.
|
||||||
|
*/
|
||||||
|
public NameFinder()
|
||||||
|
{
|
||||||
|
executable = getExecutable();
|
||||||
|
Runtime runtime = Runtime.getRuntime();
|
||||||
|
if (demangle)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String[] exec = new String[] {"c++filt", "-s", "java"};
|
||||||
|
cppfilt = runtime.exec(exec);
|
||||||
|
cppfiltIn = new BufferedReader
|
||||||
|
(new InputStreamReader(cppfilt.getInputStream()));
|
||||||
|
cppfiltOut = new BufferedWriter
|
||||||
|
(new OutputStreamWriter(cppfilt.getOutputStream()));
|
||||||
|
}
|
||||||
|
catch (IOException ioe)
|
||||||
|
{
|
||||||
|
if (cppfilt != null)
|
||||||
|
cppfilt.destroy();
|
||||||
|
cppfilt = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_addr2line)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String[] exec = new String[] {"addr2line", "-f", "-e", executable};
|
||||||
|
addr2line = runtime.exec(exec);
|
||||||
|
}
|
||||||
|
catch (IOException ioe)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String[] exec = new String[] {"addr2name.awk", executable};
|
||||||
|
addr2line = runtime.exec(exec);
|
||||||
|
}
|
||||||
|
catch (IOException ioe2) { addr2line = null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr2line != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addr2lineIn = new BufferedReader
|
||||||
|
(new InputStreamReader(addr2line.getInputStream()));
|
||||||
|
addr2lineOut = new BufferedWriter
|
||||||
|
(new OutputStreamWriter(addr2line.getOutputStream()));
|
||||||
|
}
|
||||||
|
catch (IOException ioe)
|
||||||
|
{
|
||||||
|
addr2line.destroy();
|
||||||
|
addr2line = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the currently running process.
|
||||||
|
*/
|
||||||
|
native private static String getExecutable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to use dladdr to create the nth StackTraceElement from the given
|
||||||
|
* addresses. Returns null on failure.
|
||||||
|
*/
|
||||||
|
native private StackTraceElement dladdrLookup(RawData addrs, int n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nth element from the stack as a hex encoded String.
|
||||||
|
*/
|
||||||
|
native private String getAddrAsString(RawData addrs, int n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the nth StackTraceElement from the given native stacktrace.
|
||||||
|
*/
|
||||||
|
private StackTraceElement lookup(RawData addrs, int n)
|
||||||
|
{
|
||||||
|
StackTraceElement result;
|
||||||
|
|
||||||
|
result = dladdrLookup(addrs, n);
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
String name = null;
|
||||||
|
String file = null;
|
||||||
|
String hex = getAddrAsString(addrs, n);
|
||||||
|
|
||||||
|
if (addr2line != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addr2lineOut.write(hex);
|
||||||
|
addr2lineOut.newLine();
|
||||||
|
addr2lineOut.flush();
|
||||||
|
name = addr2lineIn.readLine();
|
||||||
|
file = addr2lineIn.readLine();
|
||||||
|
}
|
||||||
|
catch (IOException ioe) { addr2line = null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == null || "??".equals(name))
|
||||||
|
name = hex;
|
||||||
|
|
||||||
|
result = createStackTraceElement(name, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an Throwable and a native stacktrace returns an array of
|
||||||
|
* StackTraceElement containing class, method, file and linenumbers.
|
||||||
|
*/
|
||||||
|
public StackTraceElement[] lookup(Throwable t, RawData addrs, int length)
|
||||||
|
{
|
||||||
|
StackTraceElement[] elements = new StackTraceElement[length];
|
||||||
|
for (int i=0; i < length; i++)
|
||||||
|
elements[i] = lookup(addrs, i);
|
||||||
|
|
||||||
|
if (demangle && sanitize)
|
||||||
|
return sanitizeStack(elements, t);
|
||||||
|
else
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes calls to initialize exceptions and the runtime system from
|
||||||
|
* the stack trace including stack frames of which nothing usefull is known.
|
||||||
|
* Throw away the top of the stack till we find the constructor(s)
|
||||||
|
* of this Throwable or at least the contructors of java.lang.Throwable
|
||||||
|
* or the actual fillInStackTrace call.
|
||||||
|
* Also throw away from the top everything before and including a runtime
|
||||||
|
* _Jv_Throw call.
|
||||||
|
*/
|
||||||
|
private static StackTraceElement[] sanitizeStack(StackTraceElement[] elements,
|
||||||
|
Throwable t)
|
||||||
|
{
|
||||||
|
StackTraceElement[] stack;
|
||||||
|
|
||||||
|
String className = t.getClass().getName();
|
||||||
|
String consName;
|
||||||
|
int lastDot = className.lastIndexOf('.');
|
||||||
|
if (lastDot == -1)
|
||||||
|
consName = className + '(';
|
||||||
|
else
|
||||||
|
consName = className.substring(lastDot + 1) + '(';
|
||||||
|
|
||||||
|
int unknown = 0;
|
||||||
|
int last_throw = -1;
|
||||||
|
int length = elements.length;
|
||||||
|
int end = length-1;
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
String CName = elements[i].getClassName();
|
||||||
|
String MName = elements[i].getMethodName();
|
||||||
|
if ((CName == null && MName != null && MName.startsWith("_Jv_Throw"))
|
||||||
|
||
|
||||||
|
(CName != null
|
||||||
|
&& (CName.equals(className)
|
||||||
|
|| CName.equals("java.lang.Throwable")
|
||||||
|
|| CName.equals("java.lang.VMThrowable"))
|
||||||
|
&& MName != null
|
||||||
|
&& (MName.startsWith(consName)
|
||||||
|
|| MName.startsWith("Throwable(")
|
||||||
|
|| MName.startsWith("fillInStackTrace("))))
|
||||||
|
last_throw = i;
|
||||||
|
else if (remove_unknown && CName == null
|
||||||
|
&& (MName == null || MName.startsWith("0x")))
|
||||||
|
unknown++;
|
||||||
|
else if ("main(java.lang.String[])".equals(MName))
|
||||||
|
{
|
||||||
|
end = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 have no
|
||||||
|
// usefull information whatsoever unless that means we filter out all info.
|
||||||
|
int nr_elements = end-begin-unknown+1;
|
||||||
|
if ((begin > 0 || end < length-1 || unknown > 0) && nr_elements > 0)
|
||||||
|
{
|
||||||
|
stack = new StackTraceElement[nr_elements];
|
||||||
|
int pos =0;
|
||||||
|
for (int i=begin; i<=end; i++)
|
||||||
|
{
|
||||||
|
String MName;
|
||||||
|
if (unknown == 0
|
||||||
|
|| !(elements[i].getClassName() == null
|
||||||
|
&& ((MName = elements[i].getMethodName()) == null
|
||||||
|
|| MName.startsWith("0x"))))
|
||||||
|
{
|
||||||
|
stack[pos] = elements[i];
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stack = elements;
|
||||||
|
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a StackTraceElement given a string and a filename.
|
||||||
|
* Splits the given string into the class and method part.
|
||||||
|
* The string name will be a demangled to a fully qualified java method
|
||||||
|
* string. The string file will be decomposed into a file name and possibly
|
||||||
|
* a line number. The name should never be null, but the file may be if it
|
||||||
|
* is unknown.
|
||||||
|
*/
|
||||||
|
private StackTraceElement createStackTraceElement(String name, String file)
|
||||||
|
{
|
||||||
|
if (!demangle)
|
||||||
|
return new StackTraceElement(file, -1, null, name, false);
|
||||||
|
|
||||||
|
String s = demangleName(name);
|
||||||
|
String methodName = s;
|
||||||
|
String className = null;
|
||||||
|
int bracket = s.indexOf('(');
|
||||||
|
if (bracket > 0)
|
||||||
|
{
|
||||||
|
int dot = s.lastIndexOf('.', bracket);
|
||||||
|
if (dot > 0)
|
||||||
|
{
|
||||||
|
className = s.substring(0, dot);
|
||||||
|
methodName = s.substring(dot+1, s.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileName = file;
|
||||||
|
int line = -1;
|
||||||
|
if (fileName != null)
|
||||||
|
{
|
||||||
|
int colon = file.indexOf(':');
|
||||||
|
if (colon > 0)
|
||||||
|
{
|
||||||
|
fileName = file.substring(0, colon);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
line = Integer.parseInt(file.substring(colon+1, file.length()));
|
||||||
|
}
|
||||||
|
catch (NumberFormatException nfe) { /* ignore */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line == 0)
|
||||||
|
line =-1;
|
||||||
|
|
||||||
|
if ("".equals(fileName) || "??".equals(fileName))
|
||||||
|
fileName = null;
|
||||||
|
else if (fileName != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fileName = new File(fileName).getCanonicalPath();
|
||||||
|
}
|
||||||
|
catch (IOException ioe) { /* ignore */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StackTraceElement(fileName, line, className, methodName, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demangles the given String if possible. Returns the demangled String or
|
||||||
|
* the original string if demangling is impossible.
|
||||||
|
*/
|
||||||
|
private String demangleName(String s)
|
||||||
|
{
|
||||||
|
if (cppfilt != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cppfiltOut.write(s);
|
||||||
|
cppfiltOut.newLine();
|
||||||
|
cppfiltOut.flush();
|
||||||
|
return cppfiltIn.readLine();
|
||||||
|
}
|
||||||
|
catch (IOException ioe) { cppfilt.destroy(); cppfilt = null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases all resources used by this NameFinder.
|
||||||
|
*/
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
if (cppfilt != null)
|
||||||
|
cppfilt.destroy();
|
||||||
|
|
||||||
|
if (addr2line != null)
|
||||||
|
addr2line.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls close to get rid of all resources.
|
||||||
|
*/
|
||||||
|
protected void finalize()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
// natNameFinder.cc - native helper methods for NameFiner.java
|
||||||
|
|
||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc
|
||||||
|
|
||||||
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
This software is copyrighted work licensed under the terms of the
|
||||||
|
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mark Wielaard (mark@klomp.org)
|
||||||
|
* Based on the old name-finder.cc by Andrew Haley <aph@cygnus.com>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <gcj/cni.h>
|
||||||
|
#include <jvm.h>
|
||||||
|
#include <java/lang/String.h>
|
||||||
|
#include <java/lang/StackTraceElement.h>
|
||||||
|
|
||||||
|
#include <gnu/gcj/runtime/NameFinder.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_DLFCN_H
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
java::lang::String*
|
||||||
|
gnu::gcj::runtime::NameFinder::getExecutable (void)
|
||||||
|
{
|
||||||
|
return JvNewStringLatin1 (_Jv_ThisExecutable ());
|
||||||
|
}
|
||||||
|
|
||||||
|
java::lang::String*
|
||||||
|
gnu::gcj::runtime::NameFinder::getAddrAsString(RawData* addrs, jint n)
|
||||||
|
{
|
||||||
|
void **p = (void **) addrs;
|
||||||
|
typedef unsigned word_t __attribute ((mode (word)));
|
||||||
|
word_t w = (word_t) p[n];
|
||||||
|
int digits = sizeof (void *) * 2;
|
||||||
|
char hex[digits+5];
|
||||||
|
|
||||||
|
strcpy (hex, "0x");
|
||||||
|
for (int i = digits - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
int digit = w % 16;
|
||||||
|
|
||||||
|
w /= 16;
|
||||||
|
hex[i+2] = digit > 9 ? 'a' + digit - 10 : '0' + digit;
|
||||||
|
}
|
||||||
|
hex [digits+2] = 0;
|
||||||
|
|
||||||
|
return JvNewStringLatin1(hex);
|
||||||
|
}
|
||||||
|
|
||||||
|
java::lang::StackTraceElement*
|
||||||
|
gnu::gcj::runtime::NameFinder::dladdrLookup(RawData* addrs, jint n)
|
||||||
|
{
|
||||||
|
#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
|
||||||
|
extern char **_Jv_argv;
|
||||||
|
char name[1024];
|
||||||
|
char file_name[1024];
|
||||||
|
void **stack = (void **) addrs;
|
||||||
|
void* p = stack[n];
|
||||||
|
Dl_info dl_info;
|
||||||
|
|
||||||
|
if (dladdr (p, &dl_info))
|
||||||
|
{
|
||||||
|
if (dl_info.dli_fname)
|
||||||
|
strncpy (file_name, dl_info.dli_fname, sizeof file_name);
|
||||||
|
if (dl_info.dli_sname)
|
||||||
|
strncpy (name, dl_info.dli_sname, sizeof name);
|
||||||
|
|
||||||
|
/* Don't trust dladdr() if the address is from the main program. */
|
||||||
|
if (dl_info.dli_fname != NULL
|
||||||
|
&& dl_info.dli_sname != NULL
|
||||||
|
&& (_Jv_argv == NULL || strcmp (file_name, _Jv_argv[0]) != 0))
|
||||||
|
return createStackTraceElement (JvNewStringLatin1 (name),
|
||||||
|
JvNewStringLatin1 (file_name));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
// name-finder.h - Convert addresses to names
|
|
||||||
|
|
||||||
/* Copyright (C) 2000, 2002 Free Software Foundation, Inc
|
|
||||||
|
|
||||||
This file is part of libgcj.
|
|
||||||
|
|
||||||
This software is copyrighted work licensed under the terms of the
|
|
||||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|
||||||
details. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Haley <aph@cygnus.com>
|
|
||||||
* @date Jan 6 2000
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gcj/cni.h>
|
|
||||||
#include <jvm.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_WAIT_H
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <java/lang/StackTraceElement.h>
|
|
||||||
|
|
||||||
/* _Jv_name_finder is a class wrapper around a mechanism that can
|
|
||||||
convert addresses of methods to their names and the names of files
|
|
||||||
in which they appear. */
|
|
||||||
|
|
||||||
class _Jv_name_finder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
_Jv_name_finder (char *executable);
|
|
||||||
~_Jv_name_finder ()
|
|
||||||
{
|
|
||||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK)
|
|
||||||
myclose (f_pipe[0]);
|
|
||||||
myclose (f_pipe[1]);
|
|
||||||
myclose (b_pipe[0]);
|
|
||||||
myclose (b_pipe[1]);
|
|
||||||
if (b_pipe_fd != NULL)
|
|
||||||
fclose (b_pipe_fd);
|
|
||||||
|
|
||||||
myclose (f2_pipe[0]);
|
|
||||||
myclose (f2_pipe[1]);
|
|
||||||
myclose (b2_pipe[0]);
|
|
||||||
myclose (b2_pipe[1]);
|
|
||||||
if (b2_pipe_fd != NULL)
|
|
||||||
fclose (b2_pipe_fd);
|
|
||||||
|
|
||||||
if (pid >= 0)
|
|
||||||
{
|
|
||||||
int wstat;
|
|
||||||
// We don't care about errors here.
|
|
||||||
waitpid (pid, &wstat, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pid2 >= 0)
|
|
||||||
{
|
|
||||||
int wstat;
|
|
||||||
// We don't care about errors here.
|
|
||||||
waitpid (pid2, &wstat, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a pointer to a function or method, try to convert it into a
|
|
||||||
name and the appropriate line and source file. The caller passes
|
|
||||||
the code pointer in p.
|
|
||||||
|
|
||||||
Returns NULL if the lookup fails. Even if this happens, the field
|
|
||||||
hex will have been correctly filled in with the pointer. */
|
|
||||||
|
|
||||||
java::lang::StackTraceElement* lookup (void *p);
|
|
||||||
|
|
||||||
char hex[sizeof (void *) * 2 + 5];
|
|
||||||
|
|
||||||
private:
|
|
||||||
void toHex (void *p);
|
|
||||||
java::lang::StackTraceElement* createStackTraceElement(char *s, char *f);
|
|
||||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK)
|
|
||||||
pid_t pid, pid2;
|
|
||||||
int f_pipe[2], b_pipe[2], f2_pipe[2], b2_pipe[2];
|
|
||||||
FILE *b_pipe_fd, *b2_pipe_fd;
|
|
||||||
int demangling_error, lookup_error;
|
|
||||||
|
|
||||||
// Close a descriptor only if it has not been closed.
|
|
||||||
void myclose (int fd)
|
|
||||||
{
|
|
||||||
if (fd != -1)
|
|
||||||
close (fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
@ -46,11 +46,6 @@ import java.io.ObjectInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Tom Tromey <tromey@cygnus.com>
|
|
||||||
* @date October 30, 1998
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
||||||
* "The Java Language Specification", ISBN 0-201-63451-1
|
* "The Java Language Specification", ISBN 0-201-63451-1
|
||||||
* Status: Sufficient for compiled code, but methods applicable to
|
* Status: Sufficient for compiled code, but methods applicable to
|
||||||
|
|
@ -116,7 +111,7 @@ import java.io.OutputStream;
|
||||||
* @author Tom Tromey
|
* @author Tom Tromey
|
||||||
* @author Eric Blake <ebb9@email.byu.edu>
|
* @author Eric Blake <ebb9@email.byu.edu>
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
* @status still missing 1.4 functionality
|
* @status updated to 1.4
|
||||||
*/
|
*/
|
||||||
public class Throwable implements Serializable
|
public class Throwable implements Serializable
|
||||||
{
|
{
|
||||||
|
|
@ -130,7 +125,7 @@ public class Throwable implements Serializable
|
||||||
*
|
*
|
||||||
* @serial specific details about the exception, may be null
|
* @serial specific details about the exception, may be null
|
||||||
*/
|
*/
|
||||||
private String detailMessage;
|
private final String detailMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cause of the throwable, including null for an unknown or non-chained
|
* The cause of the throwable, including null for an unknown or non-chained
|
||||||
|
|
@ -374,7 +369,7 @@ public class Throwable implements Serializable
|
||||||
*/
|
*/
|
||||||
public void printStackTrace(PrintStream s)
|
public void printStackTrace(PrintStream s)
|
||||||
{
|
{
|
||||||
printStackTrace(new PrintWriter(s));
|
s.print(stackTraceString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -409,72 +404,88 @@ public class Throwable implements Serializable
|
||||||
*/
|
*/
|
||||||
public void printStackTrace (PrintWriter pw)
|
public void printStackTrace (PrintWriter pw)
|
||||||
{
|
{
|
||||||
// First line
|
pw.print(stackTraceString());
|
||||||
pw.println(toString());
|
}
|
||||||
|
|
||||||
// The stacktrace
|
private static final String nl = System.getProperty("line.separator");
|
||||||
|
// Create whole stack trace in a stringbuffer so we don't have to print
|
||||||
|
// it line by line. This prevents printing multiple stack traces from
|
||||||
|
// different threads to get mixed up when written to the same PrintWriter.
|
||||||
|
private String stackTraceString()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// Main stacktrace
|
||||||
StackTraceElement[] stack = getStackTrace();
|
StackTraceElement[] stack = getStackTrace();
|
||||||
if (stack == null || stack.length == 0)
|
stackTraceStringBuffer(sb, this.toString(), stack, 0);
|
||||||
{
|
|
||||||
pw.println(" <<No stacktrace available>>");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < stack.length; i++)
|
|
||||||
pw.println(" at " + stack[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The cause(s)
|
// The cause(s)
|
||||||
Throwable cause = getCause();
|
Throwable cause = getCause();
|
||||||
while (cause != null)
|
while (cause != null)
|
||||||
{
|
{
|
||||||
// Cause first line
|
// Cause start first line
|
||||||
pw.println("Caused by: " + cause);
|
sb.append("Caused by: ");
|
||||||
|
|
||||||
// Cause stacktrace
|
// Cause stacktrace
|
||||||
StackTraceElement[] parentStack = stack;
|
StackTraceElement[] parentStack = stack;
|
||||||
stack = cause.getStackTrace();
|
stack = cause.getStackTrace();
|
||||||
if (stack == null || stack.length == 0)
|
if (parentStack == null || parentStack.length == 0)
|
||||||
{
|
stackTraceStringBuffer(sb, cause.toString(), stack, 0);
|
||||||
pw.println(" <<No stacktrace available>>");
|
|
||||||
}
|
|
||||||
else if (parentStack == null || parentStack.length == 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < stack.length; i++)
|
|
||||||
pw.println(" at " + stack[i]);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boolean equal = false; // Is rest of stack equal to parent frame?
|
int equal = 0; // Count how many of the last stack frames are equal
|
||||||
for (int i = 0; i < stack.length && ! equal; i++)
|
int frame = stack.length-1;
|
||||||
|
int parentFrame = parentStack.length-1;
|
||||||
|
while (frame > 0 && parentFrame > 0)
|
||||||
{
|
{
|
||||||
// Check if we already printed the rest of the stack
|
if (stack[frame].equals(parentStack[parentFrame]))
|
||||||
// since it was the tail of the parent stack
|
|
||||||
int remaining = stack.length - i;
|
|
||||||
int element = i;
|
|
||||||
int parentElement = parentStack.length - remaining;
|
|
||||||
equal = parentElement >= 0
|
|
||||||
&& parentElement < parentStack.length; // be optimistic
|
|
||||||
while (equal && element < stack.length)
|
|
||||||
{
|
{
|
||||||
if (stack[element].equals(parentStack[parentElement]))
|
equal++;
|
||||||
{
|
frame--;
|
||||||
element++;
|
parentFrame--;
|
||||||
parentElement++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
equal = false;
|
|
||||||
}
|
}
|
||||||
// Print stacktrace element or indicate the rest is equal
|
|
||||||
if (! equal)
|
|
||||||
pw.println(" at " + stack[i]);
|
|
||||||
else
|
else
|
||||||
pw.println(" ..." + remaining + " more");
|
break;
|
||||||
}
|
}
|
||||||
|
stackTraceStringBuffer(sb, cause.toString(), stack, equal);
|
||||||
}
|
}
|
||||||
cause = cause.getCause();
|
cause = cause.getCause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds to the given StringBuffer a line containing the name and
|
||||||
|
// all stacktrace elements minus the last equal ones.
|
||||||
|
private static void stackTraceStringBuffer(StringBuffer sb, String name,
|
||||||
|
StackTraceElement[] stack, int equal)
|
||||||
|
{
|
||||||
|
// (finish) first line
|
||||||
|
sb.append(name);
|
||||||
|
sb.append(nl);
|
||||||
|
|
||||||
|
// The stacktrace
|
||||||
|
if (stack == null || stack.length == 0)
|
||||||
|
{
|
||||||
|
sb.append(" <<No stacktrace available>>");
|
||||||
|
sb.append(nl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < stack.length-equal; i++)
|
||||||
|
{
|
||||||
|
sb.append(" at ");
|
||||||
|
sb.append(stack[i] == null ? "<<Unknown>>" : stack[i].toString());
|
||||||
|
sb.append(nl);
|
||||||
|
}
|
||||||
|
if (equal > 0)
|
||||||
|
{
|
||||||
|
sb.append(" ...");
|
||||||
|
sb.append(equal);
|
||||||
|
sb.append(" more");
|
||||||
|
sb.append(nl);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -483,7 +494,13 @@ public class Throwable implements Serializable
|
||||||
* @return this same throwable
|
* @return this same throwable
|
||||||
* @see #printStackTrace()
|
* @see #printStackTrace()
|
||||||
*/
|
*/
|
||||||
public native Throwable fillInStackTrace();
|
public Throwable fillInStackTrace()
|
||||||
|
{
|
||||||
|
vmState = VMThrowable.fillInStackTrace(this);
|
||||||
|
stackTrace = null; // Should be regenerated when used.
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to the information printed in {@link #printStackTrace()}.
|
* Provides access to the information printed in {@link #printStackTrace()}.
|
||||||
|
|
@ -499,7 +516,13 @@ public class Throwable implements Serializable
|
||||||
public StackTraceElement[] getStackTrace()
|
public StackTraceElement[] getStackTrace()
|
||||||
{
|
{
|
||||||
if (stackTrace == null)
|
if (stackTrace == null)
|
||||||
stackTrace = getStackTrace0();
|
if (vmState == null)
|
||||||
|
stackTrace = new StackTraceElement[0];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stackTrace = vmState.getStackTrace(this);
|
||||||
|
vmState = null; // No longer needed
|
||||||
|
}
|
||||||
|
|
||||||
return stackTrace;
|
return stackTrace;
|
||||||
}
|
}
|
||||||
|
|
@ -508,6 +531,10 @@ public class Throwable implements Serializable
|
||||||
* Change the stack trace manually. This method is designed for remote
|
* Change the stack trace manually. This method is designed for remote
|
||||||
* procedure calls, which intend to alter the stack trace before or after
|
* procedure calls, which intend to alter the stack trace before or after
|
||||||
* serialization according to the context of the remote call.
|
* serialization according to the context of the remote call.
|
||||||
|
* <p>
|
||||||
|
* The contents of the given stacktrace is copied so changes to the
|
||||||
|
* original * array do not change the stack trace elements of this
|
||||||
|
* throwable.
|
||||||
*
|
*
|
||||||
* @param stackTrace the new trace to use
|
* @param stackTrace the new trace to use
|
||||||
* @throws NullPointerException if stackTrace is null or has null elements
|
* @throws NullPointerException if stackTrace is null or has null elements
|
||||||
|
|
@ -515,15 +542,22 @@ public class Throwable implements Serializable
|
||||||
*/
|
*/
|
||||||
public void setStackTrace(StackTraceElement[] stackTrace)
|
public void setStackTrace(StackTraceElement[] stackTrace)
|
||||||
{
|
{
|
||||||
for (int i = stackTrace.length; --i >= 0; )
|
int i = stackTrace.length;
|
||||||
|
StackTraceElement[] st = new StackTraceElement[i];
|
||||||
|
|
||||||
|
while (--i >= 0)
|
||||||
if (stackTrace[i] == null)
|
if (stackTrace[i] == null)
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
this.stackTrace = stackTrace;
|
else
|
||||||
|
st[i] = stackTrace[i];
|
||||||
|
|
||||||
|
this.stackTrace = st;
|
||||||
}
|
}
|
||||||
|
|
||||||
private native final StackTraceElement[] getStackTrace0 ();
|
/**
|
||||||
|
* VM state when fillInStackTrace was called.
|
||||||
// Setting this flag to false prevents fillInStackTrace() from running.
|
* Used by getStackTrace() to get an array of StackTraceElements.
|
||||||
static boolean trace_enabled = true;
|
* Cleared when no longer needed.
|
||||||
private transient byte stackTraceBytes[];
|
*/
|
||||||
|
private transient VMThrowable vmState;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
/* java.lang.VMThrowable -- VM support methods for Throwable.
|
||||||
|
Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Classpath.
|
||||||
|
|
||||||
|
GNU Classpath is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GNU Classpath is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||||
|
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA.
|
||||||
|
|
||||||
|
Linking this library statically or dynamically with other modules is
|
||||||
|
making a combined work based on this library. Thus, the terms and
|
||||||
|
conditions of the GNU General Public License cover the whole
|
||||||
|
combination.
|
||||||
|
|
||||||
|
As a special exception, the copyright holders of this library give you
|
||||||
|
permission to link this library with independent modules to produce an
|
||||||
|
executable, regardless of the license terms of these independent
|
||||||
|
modules, and to copy and distribute the resulting executable under
|
||||||
|
terms of your choice, provided that you also meet, for each linked
|
||||||
|
independent module, the terms and conditions of the license of that
|
||||||
|
module. An independent module is a module which is not derived from
|
||||||
|
or based on this library. If you modify this library, you may extend
|
||||||
|
this exception to your version of the library, but you are not
|
||||||
|
obligated to do so. If you do not wish to do so, delete this
|
||||||
|
exception statement from your version. */
|
||||||
|
|
||||||
|
package java.lang;
|
||||||
|
|
||||||
|
import gnu.gcj.runtime.NameFinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VM dependant state and support methods Throwabele.
|
||||||
|
* It is deliberately package local and final and should only be accessed
|
||||||
|
* by the Throwable class.
|
||||||
|
* <p>
|
||||||
|
* This is the version used by libgcj (http://gcc.gnu.org/java/).
|
||||||
|
*
|
||||||
|
* @author Mark Wielaard (mark@klomp.org)
|
||||||
|
*/
|
||||||
|
final class VMThrowable
|
||||||
|
{
|
||||||
|
private gnu.gcj.RawData stackTraceAddrs;
|
||||||
|
private int length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private contructor, create VMThrowables with fillInStackTrace();
|
||||||
|
*/
|
||||||
|
private VMThrowable() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill in the stack trace with the current execution stack.
|
||||||
|
* Called by <code>Throwable.fillInStackTrace()</code> to get the state of
|
||||||
|
* the VM. Can return null when the VM does not support caputing the VM
|
||||||
|
* execution state.
|
||||||
|
*
|
||||||
|
* @return a new VMThrowable containing the current execution stack trace.
|
||||||
|
* @see Throwable#fillInStackTrace()
|
||||||
|
*/
|
||||||
|
static native VMThrowable fillInStackTrace(Throwable t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an <code>StackTraceElement</code> array based on the execution
|
||||||
|
* state of the VM as captured by <code>fillInStackTrace</code>.
|
||||||
|
* Called by <code>Throwable.getStackTrace()</code>.
|
||||||
|
*
|
||||||
|
* @return a non-null but possible zero length array of StackTraceElement.
|
||||||
|
* @see Throwable#getStackTrace()
|
||||||
|
*/
|
||||||
|
StackTraceElement[] getStackTrace(Throwable t)
|
||||||
|
{
|
||||||
|
StackTraceElement[] result;
|
||||||
|
if (stackTraceAddrs != null)
|
||||||
|
{
|
||||||
|
NameFinder nameFinder = new NameFinder();
|
||||||
|
result = nameFinder.lookup(t, stackTraceAddrs, length);
|
||||||
|
nameFinder.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = new StackTraceElement[0];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setting this flag to false prevents fillInStackTrace() from running.
|
||||||
|
static boolean trace_enabled = true;
|
||||||
|
}
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
// natThrowable.cc - Superclass for all exceptions.
|
|
||||||
|
|
||||||
/* Copyright (C) 2000 Free Software Foundation, Inc
|
|
||||||
|
|
||||||
This file is part of libgcj.
|
|
||||||
|
|
||||||
This software is copyrighted work licensed under the terms of the
|
|
||||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|
||||||
details. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Haley <aph@cygnus.com>
|
|
||||||
* @date Jan 6 2000
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <gcj/cni.h>
|
|
||||||
#include <jvm.h>
|
|
||||||
#include <java/lang/Object.h>
|
|
||||||
#include <java-threads.h>
|
|
||||||
#include <java/lang/Throwable.h>
|
|
||||||
#include <java/lang/StackTraceElement.h>
|
|
||||||
#include <java/io/PrintStream.h>
|
|
||||||
#include <java/io/PrintWriter.h>
|
|
||||||
#include <java/io/IOException.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_EXECINFO_H
|
|
||||||
#include <execinfo.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <name-finder.h>
|
|
||||||
|
|
||||||
/* FIXME: size of the stack trace is limited to 128 elements. It's
|
|
||||||
undoubtedly sensible to limit the stack trace, but 128 is rather
|
|
||||||
arbitrary. It may be better to configure this. */
|
|
||||||
|
|
||||||
java::lang::Throwable *
|
|
||||||
java::lang::Throwable::fillInStackTrace (void)
|
|
||||||
{
|
|
||||||
if (! trace_enabled)
|
|
||||||
return this;
|
|
||||||
#if defined (HAVE_BACKTRACE)
|
|
||||||
void *p[128];
|
|
||||||
|
|
||||||
// We subtract 1 from the number of elements because we don't want
|
|
||||||
// to include the call to fillInStackTrace in the trace.
|
|
||||||
int n = backtrace (p, 128) - 1;
|
|
||||||
|
|
||||||
if (n > 0)
|
|
||||||
{
|
|
||||||
// We copy the array below to deal with alignment issues.
|
|
||||||
stackTraceBytes = JvNewByteArray (n * sizeof p[0]);
|
|
||||||
memcpy (elements (stackTraceBytes), p+1, (n * sizeof p[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
JArray<java::lang::StackTraceElement*> *
|
|
||||||
java::lang::Throwable::getStackTrace0 ()
|
|
||||||
{
|
|
||||||
#ifdef HAVE_BACKTRACE
|
|
||||||
if (!stackTraceBytes)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
int depth = stackTraceBytes->length / sizeof (void *);
|
|
||||||
void *p[depth];
|
|
||||||
// This memcpy is esential; it ensures that the array of void* is
|
|
||||||
// correctly aligned.
|
|
||||||
memcpy (p, elements (stackTraceBytes), sizeof p);
|
|
||||||
|
|
||||||
JArray<java::lang::StackTraceElement*> *result;
|
|
||||||
java::lang::StackTraceElement** el;
|
|
||||||
result = reinterpret_cast <JArray<java::lang::StackTraceElement *>*>
|
|
||||||
(JvNewObjectArray (depth, &java::lang::StackTraceElement::class$, NULL));
|
|
||||||
el = elements (result);
|
|
||||||
|
|
||||||
_Jv_name_finder finder (_Jv_ThisExecutable ());
|
|
||||||
|
|
||||||
for (int i = 0; i < depth; i++)
|
|
||||||
el[i] = finder.lookup (p[i]);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif /* HAVE_BACKTRACE */
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
// natVMThrowable.cc - native helper methods for Throwable
|
||||||
|
|
||||||
|
/* Copyright (C) 2000, 2002 Free Software Foundation, Inc
|
||||||
|
|
||||||
|
This file is part of libgcj.
|
||||||
|
|
||||||
|
This software is copyrighted work licensed under the terms of the
|
||||||
|
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrew Haley <aph@cygnus.com>
|
||||||
|
* @author Mark Wielaard <mark@klomp.org>
|
||||||
|
*
|
||||||
|
* Native helper methods for VM specific Throwable support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <jvm.h>
|
||||||
|
#include <gcj/cni.h>
|
||||||
|
#include <gnu/gcj/RawData.h>
|
||||||
|
#include <java/lang/Object.h>
|
||||||
|
#include <java-threads.h>
|
||||||
|
#include <java/lang/Throwable.h>
|
||||||
|
#include <java/lang/VMThrowable.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_EXECINFO_H
|
||||||
|
#include <execinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: size of the stack trace is limited to 128 elements. It's
|
||||||
|
undoubtedly sensible to limit the stack trace, but 128 is rather
|
||||||
|
arbitrary. It may be better to configure this. */
|
||||||
|
|
||||||
|
java::lang::VMThrowable *
|
||||||
|
java::lang::VMThrowable::fillInStackTrace (java::lang::Throwable* t)
|
||||||
|
{
|
||||||
|
if (! trace_enabled)
|
||||||
|
return NULL;
|
||||||
|
#if defined (HAVE_BACKTRACE)
|
||||||
|
VMThrowable* state = new VMThrowable;
|
||||||
|
void *p[128];
|
||||||
|
|
||||||
|
// We subtract 1 from the number of elements because we don't want
|
||||||
|
// to include the calls to fillInStackTrace in the trace.
|
||||||
|
int n = backtrace (p, 128) - 1;
|
||||||
|
|
||||||
|
void **addrs;
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
state->length = n;
|
||||||
|
addrs = (void **) _Jv_Malloc (n * sizeof p[0]);
|
||||||
|
while (n--)
|
||||||
|
addrs[n] = p[n];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
addrs = NULL;
|
||||||
|
|
||||||
|
state->stackTraceAddrs = reinterpret_cast<gnu::gcj::RawData *> (addrs);
|
||||||
|
|
||||||
|
return state;
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
@ -1,356 +0,0 @@
|
||||||
// name-finder.cc - Convert addresses to names
|
|
||||||
|
|
||||||
/* Copyright (C) 2000, 2002 Free Software Foundation, Inc
|
|
||||||
|
|
||||||
This file is part of libgcj.
|
|
||||||
|
|
||||||
This software is copyrighted work licensed under the terms of the
|
|
||||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
|
||||||
details. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Haley <aph@cygnus.com>
|
|
||||||
* @date Jan 6 2000
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* _Jv_name_finder is a class wrapper around a mechanism that can
|
|
||||||
convert address of methods to their names and the names of files in
|
|
||||||
which they appear.
|
|
||||||
|
|
||||||
Right now, the only implementation of this involves running a copy
|
|
||||||
of addr2line, but at some point it is worth building this
|
|
||||||
functionality into libgcj, if only for embedded systems. */
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <gcj/cni.h>
|
|
||||||
#include <jvm.h>
|
|
||||||
#include <java/lang/Object.h>
|
|
||||||
#include <java-threads.h>
|
|
||||||
#include <java/lang/Throwable.h>
|
|
||||||
#include <java/io/PrintStream.h>
|
|
||||||
#include <java/io/PrintWriter.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_DLFCN_H
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <name-finder.h>
|
|
||||||
|
|
||||||
/* Create a new name finder which will perform address lookups on an
|
|
||||||
executable. */
|
|
||||||
|
|
||||||
_Jv_name_finder::_Jv_name_finder (char *executable)
|
|
||||||
{
|
|
||||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
|
|
||||||
demangling_error = lookup_error = 0;
|
|
||||||
|
|
||||||
// Initialize file descriptors so that shutdown works properly.
|
|
||||||
f_pipe[0] = -1;
|
|
||||||
f_pipe[1] = -1;
|
|
||||||
b_pipe[0] = -1;
|
|
||||||
b_pipe[1] = -1;
|
|
||||||
b_pipe_fd = NULL;
|
|
||||||
|
|
||||||
f2_pipe[0] = -1;
|
|
||||||
f2_pipe[1] = -1;
|
|
||||||
b2_pipe[0] = -1;
|
|
||||||
b2_pipe[1] = -1;
|
|
||||||
b2_pipe_fd = NULL;
|
|
||||||
|
|
||||||
// addr2line helper process.
|
|
||||||
|
|
||||||
char *argv[5];
|
|
||||||
{
|
|
||||||
int arg = 0;
|
|
||||||
#ifdef __ia64__
|
|
||||||
argv[arg++] = "addr2name.awk";
|
|
||||||
#else
|
|
||||||
argv[arg++] = "addr2line";
|
|
||||||
argv[arg++] = "-f";
|
|
||||||
argv[arg++] = "-e";
|
|
||||||
#endif
|
|
||||||
argv[arg++] = executable;
|
|
||||||
argv[arg] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
lookup_error |= pipe (f_pipe) < 0;
|
|
||||||
lookup_error |= pipe (b_pipe) < 0;
|
|
||||||
|
|
||||||
if (lookup_error)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pid = fork ();
|
|
||||||
if (pid == 0)
|
|
||||||
{
|
|
||||||
close (f_pipe[1]);
|
|
||||||
close (b_pipe[0]);
|
|
||||||
dup2 (f_pipe[0], fileno (stdin));
|
|
||||||
dup2 (b_pipe[1], fileno (stdout));
|
|
||||||
execvp (argv[0], argv);
|
|
||||||
_exit (127);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close child end of pipes. Set local descriptors to -1 so we
|
|
||||||
// don't try to close the fd again.
|
|
||||||
close (f_pipe [0]);
|
|
||||||
f_pipe[0] = -1;
|
|
||||||
close (b_pipe [1]);
|
|
||||||
b_pipe[1] = -1;
|
|
||||||
|
|
||||||
if (pid < 0)
|
|
||||||
{
|
|
||||||
lookup_error |= 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
b_pipe_fd = fdopen (b_pipe[0], "r");
|
|
||||||
lookup_error |= !b_pipe_fd;
|
|
||||||
|
|
||||||
if (! lookup_error)
|
|
||||||
{
|
|
||||||
// Don't try to close the fd twice.
|
|
||||||
b_pipe[0] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// c++filt helper process.
|
|
||||||
|
|
||||||
char *argv2[4];
|
|
||||||
argv2[0] = "c++filt";
|
|
||||||
argv2[1] = "-s";
|
|
||||||
argv2[2] = "java";
|
|
||||||
argv2[3] = NULL;
|
|
||||||
|
|
||||||
demangling_error |= pipe (f2_pipe) < 0;
|
|
||||||
demangling_error |= pipe (b2_pipe) < 0;
|
|
||||||
|
|
||||||
if (demangling_error)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pid2 = fork ();
|
|
||||||
if (pid2 == 0)
|
|
||||||
{
|
|
||||||
close (f2_pipe[1]);
|
|
||||||
close (b2_pipe[0]);
|
|
||||||
dup2 (f2_pipe[0], fileno (stdin));
|
|
||||||
dup2 (b2_pipe[1], fileno (stdout));
|
|
||||||
execvp (argv2[0], argv2);
|
|
||||||
_exit (127);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close child end of pipes. Set local descriptors to -1 so we
|
|
||||||
// don't try to close the fd again.
|
|
||||||
close (f2_pipe [0]);
|
|
||||||
f2_pipe[0] = -1;
|
|
||||||
close (b2_pipe [1]);
|
|
||||||
b2_pipe[1] = -1;
|
|
||||||
|
|
||||||
if (pid2 < 0)
|
|
||||||
{
|
|
||||||
demangling_error |= 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
b2_pipe_fd = fdopen (b2_pipe[0], "r");
|
|
||||||
demangling_error |= !b2_pipe_fd;
|
|
||||||
|
|
||||||
if (! demangling_error)
|
|
||||||
{
|
|
||||||
// Don't try to close the fd twice.
|
|
||||||
b2_pipe[0] = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert a pointer to hex. */
|
|
||||||
|
|
||||||
void
|
|
||||||
_Jv_name_finder::toHex (void *p)
|
|
||||||
{
|
|
||||||
typedef unsigned word_t __attribute ((mode (word)));
|
|
||||||
word_t n = (word_t) p;
|
|
||||||
int digits = sizeof (void *) * 2;
|
|
||||||
|
|
||||||
strcpy (hex, "0x");
|
|
||||||
for (int i = digits - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
int digit = n % 16;
|
|
||||||
|
|
||||||
n /= 16;
|
|
||||||
hex[i+2] = digit > 9 ? 'a' + digit - 10 : '0' + digit;
|
|
||||||
}
|
|
||||||
hex [digits+2] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Creates a StackTraceElement given a string and a filename.
|
|
||||||
Splits the given string into the class and method part.
|
|
||||||
The string s will be a demangled to a fully qualified java method string.
|
|
||||||
The string f will be decomposed into a file name and a possible line number.
|
|
||||||
The given strings will be altered. */
|
|
||||||
|
|
||||||
java::lang::StackTraceElement*
|
|
||||||
_Jv_name_finder::createStackTraceElement(char *s, char *f)
|
|
||||||
{
|
|
||||||
char *c;
|
|
||||||
char *class_name = NULL;
|
|
||||||
char *method_name = NULL;
|
|
||||||
|
|
||||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
|
|
||||||
if (demangling_error)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
demangling_error |= write (f2_pipe[1], s, strlen (s)) < 0;
|
|
||||||
if (demangling_error)
|
|
||||||
goto fail;
|
|
||||||
demangling_error |= write (f2_pipe[1], "\n", 1) < 0;
|
|
||||||
if (demangling_error)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
char name[1024];
|
|
||||||
demangling_error |= (fgets (name, sizeof name, b2_pipe_fd) == NULL);
|
|
||||||
if (demangling_error)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
c = strchr (name, '\n');
|
|
||||||
if (c)
|
|
||||||
*c = 0;
|
|
||||||
s = name;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
c = strchr (s, '(');
|
|
||||||
if (c)
|
|
||||||
{
|
|
||||||
while(c-->s)
|
|
||||||
if (*c == '.')
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (*c == '.')
|
|
||||||
{
|
|
||||||
*c = 0;
|
|
||||||
class_name = s;
|
|
||||||
method_name = c+1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
class_name = NULL;
|
|
||||||
method_name = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
class_name = NULL;
|
|
||||||
method_name = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get line number
|
|
||||||
int line_number;
|
|
||||||
c = strrchr (f, ':');
|
|
||||||
if (c)
|
|
||||||
{
|
|
||||||
if (c[1] != 0)
|
|
||||||
line_number = atoi(c+1);
|
|
||||||
else
|
|
||||||
line_number = -1;
|
|
||||||
*c = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
line_number = -1;
|
|
||||||
c = strchr (f, '\n');
|
|
||||||
if (c)
|
|
||||||
*c = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
return new java::lang::StackTraceElement(
|
|
||||||
f ? JvNewStringLatin1 (f) : NULL,
|
|
||||||
line_number,
|
|
||||||
class_name ? JvNewStringLatin1 (class_name) : NULL,
|
|
||||||
JvNewStringLatin1 (method_name ? method_name : s),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a pointer to a function or method, try to convert it into a
|
|
||||||
name and the appropriate line and source file. The caller passes
|
|
||||||
the code pointer in p.
|
|
||||||
|
|
||||||
Returns false if the lookup fails. Even if this happens, the field
|
|
||||||
he will have been correctly filled in with the pointer. */
|
|
||||||
|
|
||||||
java::lang::StackTraceElement*
|
|
||||||
_Jv_name_finder::lookup (void *p)
|
|
||||||
{
|
|
||||||
extern char **_Jv_argv;
|
|
||||||
toHex (p);
|
|
||||||
|
|
||||||
char name[1024];
|
|
||||||
char file_name[1024];
|
|
||||||
|
|
||||||
file_name[0] = 0;
|
|
||||||
|
|
||||||
#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
|
|
||||||
{
|
|
||||||
Dl_info dl_info;
|
|
||||||
|
|
||||||
if (dladdr (p, &dl_info))
|
|
||||||
{
|
|
||||||
if (dl_info.dli_fname)
|
|
||||||
strncpy (file_name, dl_info.dli_fname, sizeof file_name);
|
|
||||||
if (dl_info.dli_sname)
|
|
||||||
strncpy (name, dl_info.dli_sname, sizeof name);
|
|
||||||
|
|
||||||
/* Don't trust dladdr() if the address is from the main program. */
|
|
||||||
if (dl_info.dli_fname != NULL
|
|
||||||
&& dl_info.dli_sname != NULL
|
|
||||||
&& (_Jv_argv == NULL || strcmp (file_name, _Jv_argv[0]) != 0))
|
|
||||||
return createStackTraceElement (name, file_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memcpy (name, hex, strlen (hex) + 1);
|
|
||||||
|
|
||||||
#if defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP)
|
|
||||||
if (lookup_error)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
lookup_error |= write (f_pipe[1], hex, strlen (hex)) < 0;
|
|
||||||
if (lookup_error)
|
|
||||||
goto fail;
|
|
||||||
lookup_error |= write (f_pipe[1], "\n", 1) < 0;
|
|
||||||
if (lookup_error)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
lookup_error |= (fgets (name, sizeof name, b_pipe_fd) == NULL);
|
|
||||||
if (lookup_error)
|
|
||||||
goto fail;
|
|
||||||
lookup_error |= (fgets (file_name, sizeof file_name, b_pipe_fd) == NULL);
|
|
||||||
if (lookup_error)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
{
|
|
||||||
char *newline = strchr (name, '\n');
|
|
||||||
if (newline)
|
|
||||||
*newline = 0;
|
|
||||||
}
|
|
||||||
#endif /* defined (HAVE_PIPE) && defined (HAVE_FORK) && defined (HAVE_EXECVP) */
|
|
||||||
|
|
||||||
fail:
|
|
||||||
return (createStackTraceElement (name, file_name));
|
|
||||||
}
|
|
||||||
|
|
@ -53,6 +53,7 @@ details. */
|
||||||
#include <java/lang/NullPointerException.h>
|
#include <java/lang/NullPointerException.h>
|
||||||
#include <java/lang/OutOfMemoryError.h>
|
#include <java/lang/OutOfMemoryError.h>
|
||||||
#include <java/lang/System.h>
|
#include <java/lang/System.h>
|
||||||
|
#include <java/lang/VMThrowable.h>
|
||||||
#include <java/lang/reflect/Modifier.h>
|
#include <java/lang/reflect/Modifier.h>
|
||||||
#include <java/io/PrintStream.h>
|
#include <java/io/PrintStream.h>
|
||||||
#include <java/lang/UnsatisfiedLinkError.h>
|
#include <java/lang/UnsatisfiedLinkError.h>
|
||||||
|
|
@ -910,8 +911,8 @@ _Jv_CreateJavaVM (void* /*vm_args*/)
|
||||||
_Jv_InitPrimClass (&_Jv_voidClass, "void", 'V', 0, &_Jv_voidVTable);
|
_Jv_InitPrimClass (&_Jv_voidClass, "void", 'V', 0, &_Jv_voidVTable);
|
||||||
|
|
||||||
// Turn stack trace generation off while creating exception objects.
|
// Turn stack trace generation off while creating exception objects.
|
||||||
_Jv_InitClass (&java::lang::Throwable::class$);
|
_Jv_InitClass (&java::lang::VMThrowable::class$);
|
||||||
java::lang::Throwable::trace_enabled = 0;
|
java::lang::VMThrowable::trace_enabled = 0;
|
||||||
|
|
||||||
INIT_SEGV;
|
INIT_SEGV;
|
||||||
#ifdef HANDLE_FPE
|
#ifdef HANDLE_FPE
|
||||||
|
|
@ -923,7 +924,7 @@ _Jv_CreateJavaVM (void* /*vm_args*/)
|
||||||
|
|
||||||
no_memory = new java::lang::OutOfMemoryError;
|
no_memory = new java::lang::OutOfMemoryError;
|
||||||
|
|
||||||
java::lang::Throwable::trace_enabled = 1;
|
java::lang::VMThrowable::trace_enabled = 1;
|
||||||
|
|
||||||
#ifdef USE_LTDL
|
#ifdef USE_LTDL
|
||||||
LTDL_SET_PRELOADED_SYMBOLS ();
|
LTDL_SET_PRELOADED_SYMBOLS ();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue