This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: Add raw address to java stack trace if line number unavailable.
- From: David Daney <ddaney at avtrex dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 05 Jun 2006 15:45:28 -0700
- Subject: Patch: Add raw address to java stack trace if line number unavailable.
This patch adds a new system property
'gnu.gcj.runtime.NameFinder.show_raw' that when set true will print the
IP in the stack trace if the line number is unavailable. When set the
trace will look something like this:
[daney@dl2 junk]$ ./Hello
Hello World
java.lang.NullPointerException
at Hello.f1(./Hello [8048bd5])
at Hello.main(./Hello [8048c67])
java.lang.NullPointerException
at H1.foo(./Hello [8048d53])
at Hello.main(./Hello [8048ca8])
java.lang.NullPointerException
at java.util.Date.parse(Date.java:767)
at Hello.main(./Hello [8048ce9])
You can see that libgcj was compiled with -g so java.util.Date.parse has
a line number. My test program (Hello) was compiled without -g so you
get the offset printed out along with the object name. This allows you
to use addr2line in an off-line mode to find the line numbers if desired.
This can be used in conjunction with the
'gnu.gcj.runtime.NameFinder.use_addr2line' to disable line number
generation at runtime (for better performance), but still be able to get
the line number information if desired.
Back in 3.3 and 3.4 the addresses used to print out, but that capability
was lost with the new stack trace infrastructure. So in someways you
could look at this as fixing a regression.
Currently regression testing on i686-pc-linux-gnu.
OK to commit if no regressions?
gcc/java:
2006-06-05 David Daney <ddaney@avtrex.com>
* gcj.texi (libgcj Runtime Properties): Document
gnu.gcj.runtime.NameFinder.show_raw and
gnu.gcj.runtime.NameFinder.remove_unknown.
libjava:
2006-06-05 David Daney <ddaney@avtrex.com>
* gnu/gcj/runtime/NameFinder.java (show_raw): New field.
(showRaw): New method.
* stacktrace.cc : Include gnu/gcj/runtime/StringBuffer.h.
(getLineNumberForFrame): Show IP offset in trace if line number
not available and show_raw true.
Index: libjava/stacktrace.cc
===================================================================
--- libjava/stacktrace.cc (revision 114394)
+++ libjava/stacktrace.cc (working copy)
@@ -27,6 +27,7 @@
#include <java/util/IdentityHashMap.h>
#include <gnu/java/lang/MainThread.h>
#include <gnu/gcj/runtime/NameFinder.h>
+#include <gnu/gcj/runtime/StringBuffer.h>
#include <sysdep/backtrace.h>
#include <sysdep/descriptor.h>
@@ -221,6 +222,17 @@
finder->lookup (binaryName, (jlong) offset);
*sourceFileName = finder->getSourceFile();
*lineNum = finder->getLineNum();
+ if (*lineNum == -1 && NameFinder::showRaw())
+ {
+ gnu::gcj::runtime::StringBuffer *t =
+ new gnu::gcj::runtime::StringBuffer(binaryName);
+ t->append ((jchar)' ');
+ t->append ((jchar)'[');
+ // + 1 to compensate for the - 1 adjustment above;
+ t->append (Long::toHexString (offset + 1));
+ t->append ((jchar)']');
+ *sourceFileName = t->toString();
+ }
}
#endif
}
Index: libjava/gnu/gcj/runtime/NameFinder.java
===================================================================
--- libjava/gnu/gcj/runtime/NameFinder.java (revision 114394)
+++ libjava/gnu/gcj/runtime/NameFinder.java (working copy)
@@ -67,13 +67,29 @@
("gnu.gcj.runtime.NameFinder.use_addr2line", "true")
).booleanValue();
+ private static boolean show_raw
+ = Boolean.valueOf(System.getProperty
+ ("gnu.gcj.runtime.NameFinder.show_raw", "false")
+ ).booleanValue();
+
+ /**
+ * Return true if raw addresses should be printed in stacktraces
+ * when no line number information is available.
+ */
+ static final boolean showRaw()
+ {
+ return show_raw;
+ }
+
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.
+ /**
+ * Return true if non-Java frames should be removed from stack
+ * traces.
+ */
static final boolean removeUnknown()
{
return remove_unknown;
Index: gcc/java/gcj.texi
===================================================================
--- gcc/java/gcj.texi (revision 114394)
+++ gcc/java/gcj.texi (working copy)
@@ -2793,6 +2793,21 @@
significantly for applications that print stack traces or make logging calls
frequently.
+@item gnu.gcj.runtime.NameFinder.show_raw
+Whether the address of a stack frame should be printed when the line
+number is unavailable. Setting this to @code{true} will cause the name
+of the object and the offset within that object to be printed when no
+line number is available. This allows for off-line decoding of
+stack traces if necessary debug information is available. The default
+is @code{false}, no raw addresses are printed.
+
+@item gnu.gcj.runtime.NameFinder.remove_unknown
+Whether stack frames for non-java code should be included in a stack
+trace. The default value is @code{true}, stack frames for non-java
+code are suppressed. Setting this to @code{false} will cause any
+non-java stack frames to be printed in addition to frames for the java
+code.
+
@item gnu.gcj.runtime.VMClassLoader.library_control
This controls how shared libraries are automatically loaded by the
built-in class loader. If this property is set to @samp{full}, a full