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


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

Patch: 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

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