GIJ segfaults on
java-puzzlers/5-exceptional-puzzlers/puzzle-45/Workout.java from Bloch
and Gafter's latest book.  (This "puzzle" is due to Jim Hugunin of
Jython and IronPython fame.)

| $ curl -O http://www.javapuzzlers.com/java-puzzlers.zip
|   % Total    % Received % Xferd  Average Speed   Time    Time     Time 
Current
|                                  Dload  Upload   Total   Spent    Left  Speed
| 100 61564  100 61564    0     0  37113      0  0:00:01  0:00:01 --:--:--
43957
| $ unzip -q java-puzzlers.zip 
| $ gcj -C java-puzzlers/5-exceptional-puzzlers/puzzle-45/Workout.java
| $ gij -classpath java-puzzlers/5-exceptional-puzzlers/puzzle-45 Workout
| Segmentation fault
| $ gcj --main=Workout
java-puzzlers/5-exceptional-puzzlers/puzzle-45/Workout.java
| $ ./a.out 
| Segmentation fault

The above is under the following version of GCJ:

| $ gcj --version
| gcj (GCC) 4.0.1 20050727 (Red Hat 4.0.1-5)
| Copyright (C) 2005 Free Software Foundation, Inc.
| This is free software; see the source for copying conditions.  There is NO
| warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I also tried running this under three other 32-bit VMs: Sun 1.4.2_08,
BEA (build 1.4.2_05-b04), and IBM 1.4.2 (build cxia32142-20050609).

The only one that seems to run this program correctly is Sun's JVM.
(Given a limited maximum stack depth, the correct behavior for this
program is to run a few gazillion years and terminate successfully.
In Sun's case, the maximum stack depth is 1024 and the program can be
expected to run for about 10^300 years, give or take a few orders of
magnitude.)

IBM's 32-bit Linux JDK starts spewing out the following diagnostic:

| Stack overflow occurred outside JITted code or Interpreter.
| Searching for valid stack frames.
| Stack trace information below may not be accurate or complete.
|  It is provided for diagnostic purposes.
| Stack overflow occurred outside JITted code or Interpreter.
| Searching for valid stack frames.
| Stack trace information below may not be accurate or complete.
|  It is provided for diagnostic purposes.
|        at Workout.workHard
| Stack overflow occurred outside JITted code or Interpreter.
| Searching for valid stack frames.
| Stack trace information below may not be accurate or complete.
|  It is provided for diagnostic purposes.
|        at Workout.workHard

I had to Ctrl-C out of it after it generated 100,000+ lines of the
above.

BEA's JDK seems to do the right thing: run till the end of times.  On
closer inspection, it turns out to get a little hosed: it stops
responding to SIGTERM and SIGQUIT.

Bryce pointed out to me that Sun's behavior is not the only correct
interpretation of the above program's semantics.  If the runtime (or
the native ahead-of-time compiler) performs tail-call optimization,
then the program may loop forever without ever terminating.  After
thinking about this over the weekend, I came to realize that this is
wrong.  There seems to be no room for TCO in this particular case:

    private static void workHard() {
        try {
            workHard();
        } finally {
            workHard();
        }
    }

Note that while the recursive call in the "finally" block *is* in the
tail position, the call in the "try" block is not.  Therefore, the
recursion cannot be transformed into a loop.


-- 
           Summary: GCJ/GIJ segfaults on Workout.java from Click and Hack's
                    "Java Puzzlers"
           Product: gcc
           Version: 4.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: java
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: vadimn at redhat dot com


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

Reply via email to