This is the mail archive of the gcc-bugs@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]

[Bug libgcj/21775] New: NPE in java::util::logging::Logger::getCallerStackFrame caused by incorrect hand-optimization


Marking this as critical because it is a NPE in logging, which can cause apps to
fail to start at all (e.g. rssowl fails to start if it hasn't been configured),
or fail to log important information.

The attached test case, when compiled with
gcj -g -o mylogger --main=Test Test.java
and run, fails with:
Exception in thread "main" java.lang.NullPointerException
   at java.lang.Class.getName() (/usr/lib/libgcj.so.6.0.0)
   at java.util.logging.Logger.getCallerStackFrame() (/usr/lib/libgcj.so.6.0.0)
   at java.util.logging.Logger.log(java.util.logging.Level, java.lang.String,
java.lang.Throwable) (/usr/lib/libgcj.so.6.0.0)
   at Test.main(java.lang.String[]) (/root/bugs/gcj/logging/Test.java:9)
   at gnu.java.lang.MainThread.call_main() (/usr/lib/libgcj.so.6.0.0)
   at gnu.java.lang.MainThread.run() (/usr/lib/libgcj.so.6.0.0)

(The stack trace itself is arguably wrong in Java terms - the NPE _actually_
occurs in Logger.getCallerStackFrame and is only detected when
java.lang.Class.getName tries to do its thing - but that's another bug. I'll
file that separately.)

The cause is here:

java::lang::StackTraceElement* 
java::util::logging::Logger::getCallerStackFrame ()
{
  gnu::gcj::runtime::StackTrace *t 
    = new gnu::gcj::runtime::StackTrace(4);
  java::lang::Class *klass = NULL;
  int i = 2;
  try
    {
      // skip until this class
      while ((klass = t->classAt (i)) != getClass())
	i++;
      // skip the stackentries of this class
      while ((klass = t->classAt (i)) == getClass() || klass == NULL)
	i++;
    }
  catch (::java::lang::ArrayIndexOutOfBoundsException *e)
    {
      // FIXME: RuntimeError
    }

klass is null at the end of this code block. But you can see that the second
loop keeps looping if klass==null. So how can klass be null? The answer is, an
ArrayIndexOutOfBoundsException _must_ have been thrown.

Next question: Why was it thrown? Answer: Because the first loop started at i=2
- but the last Logger stack entry is at position i=1. So it missed the last
Logger stack entry, so the loop never terminated normally.

Suggested fix: the initial value of i should be smaller than 2.

-- 
           Summary: NPE in java::util::logging::Logger::getCallerStackFrame
                    caused by incorrect hand-optimization
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Severity: critical
          Priority: P2
         Component: libgcj
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: greenrd at greenrd dot org
                CC: gcc-bugs at gcc dot gnu dot org,java-prs at gcc dot gnu
                    dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21775


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