BZ #53: SEGV while running Armed Bear Common Lisp

Status fields:

creation_ts:2008-03-21 11:20
component:jit
version:default branch
rep_platform:All
op_sys:Linux
bug_status:RESOLVED
resolution:FIXED
reporter:twisti@complang.tuwien.ac.at
This was reported into the Debian BTS:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=448366

Package: cacao
Version: 0.98-2
Architecture: amd64

Cacao exits with an unhandled segmentation violation when running the
compiler of Armed Bear Common Lisp. Transcript follows:

,----
| ~ $ cacao -jar ~/Desktop/abcl-0.0.9.1p.jar
| Armed Bear Common Lisp 0.0.9.1+
| Java 1.5.0 GNU Classpath
| CACAO
| Low-level initialization completed in 0.643 seconds.
| Startup completed in 19.52 seconds.
| Type ":help" for a list of available commands.
| CL-USER(1): (compile nil (lambda () 42))
| LOG: [0x0000000040043950] We received a SIGSEGV and tried to handle it, but we were
| LOG: [0x0000000040043950] unable to find a Java method at:
| LOG: [0x0000000040043950]
| LOG: [0x0000000040043950] PC=0x00002b7cff4699c0
| LOG: [0x0000000040043950]
| LOG: [0x0000000040043950] Dumping the current stacktrace:
|       at org.armedbear.lisp.Symbol.execute(Lorg/armedbear/lisp/LispObject;Lorg/armedbe
ar/lisp/LispObject;Lorg/armedbear/lisp/LispObject;Lorg/armedbear/lisp/LispObject;)Lorg/a
rmedbear/lisp/LispObject;(Symbol.java:749)
|       at org.armedbear.lisp.jvm_1205.execute([Lorg/armedbear/lisp/LispObject;)Lorg/arm
edbear/lisp/LispObject;(jvm.lisp:10347)
|       at org.armedbear.lisp.CompiledClosure.execute()Lorg/armedbear/lisp/LispObject;(C
ompiledClosure.java:44)
|       at org.armedbear.lisp.jvm_1202.execute([Lorg/armedbear/lisp/LispObject;)Lorg/arm
edbear/lisp/LispObject;(jvm.lisp:10301)
|       at org.armedbear.lisp.CompiledFunction.execute(Lorg/armedbear/lisp/LispObject;)L
org/armedbear/lisp/LispObject;(CompiledFunction.java:58)
|       at org.armedbear.lisp.Symbol.execute(Lorg/armedbear/lisp/LispObject;)Lorg/armedb
ear/lisp/LispObject;(Symbol.java:708)
|       at org.armedbear.lisp.jvm_1204.execute(Lorg/armedbear/lisp/LispObject;Lorg/armed
bear/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(jvm.lisp:10347)
|       at org.armedbear.lisp.Symbol.execute(Lorg/armedbear/lisp/LispObject;Lorg/armedbe
ar/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(Symbol.java:721)
|       at org.armedbear.lisp.jvm_1206.execute(Lorg/armedbear/lisp/LispObject;Lorg/armed
bear/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(jvm.lisp:10385)
|       at org.armedbear.lisp.Symbol.execute(Lorg/armedbear/lisp/LispObject;Lorg/armedbe
ar/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(Symbol.java:721)
|       at org.armedbear.lisp.jvm_1210.execute(Lorg/armedbear/lisp/LispObject;Lorg/armed
bear/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(jvm.lisp:10534)
|       at org.armedbear.lisp.LispThread.execute(Lorg/armedbear/lisp/LispObject;Lorg/arm
edbear/lisp/LispObject;Lorg/armedbear/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(L
ispThread.java:646)
|       at org.armedbear.lisp.Lisp.evalCall(Lorg/armedbear/lisp/LispObject;Lorg/armedbea
r/lisp/LispObject;Lorg/armedbear/lisp/Environment;Lorg/armedbear/lisp/LispThread;)Lorg/a
rmedbear/lisp/LispObject;(Lisp.java:473)
|       at org.armedbear.lisp.Lisp.eval(Lorg/armedbear/lisp/LispObject;Lorg/armedbear/li
sp/Environment;Lorg/armedbear/lisp/LispThread;)Lorg/armedbear/lisp/LispObject;(Lisp.java
:431)
|       at org.armedbear.lisp.Lisp.eval(Lorg/armedbear/lisp/LispObject;Lorg/armedbear/li
sp/Environment;Lorg/armedbear/lisp/LispThread;)Lorg/armedbear/lisp/LispObject;(Lisp.java
:429)
|       at org.armedbear.lisp.Primitives$16.execute(Lorg/armedbear/lisp/LispObject;)Lorg
/armedbear/lisp/LispObject;(Primitives.java:272)
|       at org.armedbear.lisp.LispThread.execute(Lorg/armedbear/lisp/LispObject;Lorg/arm
edbear/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(LispThread.java:625)
|       at org.armedbear.lisp.Lisp.evalCall(Lorg/armedbear/lisp/LispObject;Lorg/armedbea
r/lisp/LispObject;Lorg/armedbear/lisp/Environment;Lorg/armedbear/lisp/LispThread;)Lorg/a
rmedbear/lisp/LispObject;(Lisp.java:466)
|       at org.armedbear.lisp.Lisp.eval(Lorg/armedbear/lisp/LispObject;Lorg/armedbear/li
sp/Environment;Lorg/armedbear/lisp/LispThread;)Lorg/armedbear/lisp/LispObject;(Lisp.java
:431)
|       at org.armedbear.lisp.Primitives$137.execute(Lorg/armedbear/lisp/LispObject;Lorg
/armedbear/lisp/Environment;)Lorg/armedbear/lisp/LispObject;(Primitives.java:3670)
|       at org.armedbear.lisp.Lisp.eval(Lorg/armedbear/lisp/LispObject;Lorg/armedbear/li
sp/Environment;Lorg/armedbear/lisp/LispThread;)Lorg/armedbear/lisp/LispObject;(Lisp.java
:421)
|       at org.armedbear.lisp.Closure.execute(Lorg/armedbear/lisp/LispObject;)Lorg/armed
bear/lisp/LispObject;(Closure.java:458)
|       at org.armedbear.lisp.LispThread.execute(Lorg/armedbear/lisp/LispObject;Lorg/arm
edbear/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(LispThread.java:625)
|       at org.armedbear.lisp.Lisp$1.execute(Lorg/armedbear/lisp/LispObject;)Lorg/armedb
ear/lisp/LispObject;(Lisp.java:267)
|       at org.armedbear.lisp.Symbol.execute(Lorg/armedbear/lisp/LispObject;)Lorg/armedb
ear/lisp/LispObject;(Symbol.java:708)
|       at org.armedbear.lisp.LispThread.execute(Lorg/armedbear/lisp/LispObject;Lorg/arm
edbear/lisp/LispObject;)Lorg/armedbear/lisp/LispObject;(LispThread.java:625)
|       at org.armedbear.lisp.top_level_44.execute([Lorg/armedbear/lisp/LispObject;)Lorg
/armedbear/lisp/LispObject;(top-level.lisp:390)
|       at org.armedbear.lisp.CompiledFunction.execute()Lorg/armedbear/lisp/LispObject;(
CompiledFunction.java:51)
|       at
org.armedbear.lisp.Symbol.execute()Lorg/armedbear/lisp/LispObject;(Symbol.java:696)
|       at org.armedbear.lisp.LispThread.execute(Lorg/armedbear/lisp/LispObject;)Lorg/ar
medbear/lisp/LispObject;(LispThread.java:605)
|       at org.armedbear.lisp.top_level_45.execute()Lorg/armedbear/lisp/LispObject;(top-
level.lisp:399)
|       at org.armedbear.lisp.LispThread.execute(Lorg/armedbear/lisp/LispObject;)Lorg/ar
medbear/lisp/LispObject;(LispThread.java:605)
|       at org.armedbear.lisp.Interpreter.run()V(Interpreter.java:361)
|       at org.armedbear.lisp.Main$1.run()V(Main.java:38)
|       at java.lang.Thread.run()V(Thread.java:743)
|       at java.lang.VMThread.run()V(VMThread.java:120)
| LOG: [0x0000000040043950] Exiting...
`----

The jar file can be downloaded from

   http://downloads.sourceforge.net/abcl-web/abcl-0.0.9.1p.jar

and source code for ABCL is available at

   http://armedbear.org/abcl.html

The same code works with Kaffe version 2:1.1.8-3 and with different
versions of the Sun JDK on this machine.

Running Debian unstable, Linux 2.6.22-2-amd64, GNU libc 2.6.1.

--
Eric Marsden

Comment #1 by twisti@complang.tuwien.ac.at on 2008-03-21 12:19:49

The segmentation fault happens in the JIT compiler when building the CFG:

#9  <signal handler called>
#10 0x00002af756b19359 in cfg_insert_predecessors (bptr=0x5f3d510, pbptr=0x5f3d3d0) at
cfg.c:97
#11 0x00002af756b1995d in cfg_build (jd=0x1231e30) at cfg.c:352
#12 0x00002af756af38cb in jit_compile_intern (jd=0x1231e30) at jit.c:691
#13 0x00002af756af33d5 in jit_compile (m=0x5f21e70) at jit.c:414
#14 0x00002af756af3ddf in jit_compile_handle (m=0x5f21e70, pv=0x2aaaab1b0e18,
ra=0x2aaaab1b0e64, mptr=0x5ef5cf0) at jit.c:1061

Debugging a bit reveals that it's related to an exception handler block.

======== L012 ======== (flags: 1, bitflags: 0, next: 13, type: EXH, icount: 5):
IN:  [Ia67] javalocals: [- La0! La1 La2 La3! La4 La5 - -]
10274: 183:  COPY            Ia67 => Ta163
10274: 184:  GETFIELD        Ta163 <fieldref> org.armedbear.lisp.Throw.tag
Lorg/armedbear/lisp/LispObject; => Ta164
10274: 185:  ALOAD           L5 => La5
10274: 186:  IF_ACMPNE       Ta164 La5 --> L014
10274: 187:  NOP
OUT: [Ia67]
======== L013 ======== (flags: 1, bitflags: 0, next: 14, type: STD, icount: 4):
IN:  [Ia165] javalocals: [- La0! La1 La2 La3! La4 La5 - -]
10274: 188:  ALOAD           L4 => La4
10274: 189:  INVOKEVIRTUAL   Ia165 La4 <methodref> org.armedbear.lisp.Throw.getResult(Lo
rg/armedbear/lisp/LispThread;)Lorg/armedbear/lisp/LispObject; => Ia166
10274: 190:  GOTO            --> L015
10274: 191:  NOP
OUT: [Ia166]
======== L014 ======== (flags: 1, bitflags: 0, next: 15, type: EXH, icount: 4):
IN:  [Ia68!] javalocals: [- La0! La1 La2 La3! La4 La5 - -]
10274: 192:  ALOAD           L4 => La4
10274: 193:  INVOKEVIRTUAL   La4  pass-through: Ia68! <methodref>
org.armedbear.lisp.LispThread.popCatchTag()V
10274: 194:  ATHROW          Ia68!
10274: 195:  NOP
OUT: <null>

(gdb) up
#11 0x00002b92819f895d in cfg_build (jd=0xa2ffc0) at cfg.c:352
352                             cfg_insert_predecessors(tbptr, bptr);
(gdb) p iptr->opc
$2 = 166
(gdb) p *bptr
$3 = {nr = 12, flags = 1, bitflags = 0, type = 1, lflags = 0, icount = 5, iinstr =
0x2aaaaee6ad18, inlocals = 0x2aaaaee64898, javalocals = 0x2aaaaee64a68,
  invars = 0x2aaaaee64870, outvars = 0x2aaaaee66380, indepth = 1, outdepth = 1, varstart
= 163, varcount = 2, predecessorcount = -1, successorcount = 2,
  predecessors = 0x0, successors = 0x2aaaaee9b2b0, branchrefs = 0x0, next =
0x2aaaaee5cc60, copied_to = 0x0, original = 0x0, method = 0x2aaaaee416f0,
  inlineinfo = 0x0, mpc = -1}
(gdb) p *tbptr
$4 = {nr = 14, flags = 1, bitflags = 0, type = 1, lflags = 0, icount = 4, iinstr =
0x2aaaaee6ae80, inlocals = 0x2aaaaee64ad8, javalocals = 0x2aaaaee64ca8,
  invars = 0x2aaaaee64ab0, outvars = 0x0, indepth = 1, outdepth = 0, varstart = 167,
varcount = 0, predecessorcount = 0, successorcount = 0,
  predecessors = 0x0, successors = 0x0, branchrefs = 0x0, next = 0x2aaaaee5cda0,
copied_to = 0x0, original = 0x0, method = 0x2aaaaee416f0, inlineinfo = 0x0,
  mpc = -1}

Peter, could you look into it?

Comment #2 by pm@complang.tuwien.ac.at on 2008-03-21 15:22:53

Going to investigate that.

Comment #3 by pm@complang.tuwien.ac.at on 2008-03-21 22:28:51

The problem was that the predecessorcount of exception handler blocks was initialized to
-1 (in stack or parse) and if the exception handler really had predecessors, their
number was off by one. I wanted to remove this predecessorcount == -1 anyways, because
it causes a lot of special cases in other parts of the code as well.

Another thing: if the edge L012 -> L014 gets executed, it may not work correctly,
because of the known problem that the exception pointer being corrupted if an exception
handler is jumped to directly.

The following patch (against the debian source package of 0.98-2) fixes the crash:

*** src/vm/jit/cfg.c.orig       2008-03-21 22:00:10.000000000 +0100
--- src/vm/jit/cfg.c    2008-03-21 22:11:26.000000000 +0100
*************** bool cfg_build(jitdata *jd)
*** 127,132 ****
--- 127,139 ----
        bptr = jd->basicblocks;

        for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
+
+               if (bptr->type == BBTYPE_EXH) {
+                       /* predecessorcount for exception handlers is initialized to -1,
+                          so we need to fix it to 0. */
+                       bptr->predecessorcount += 1;
+               }
+
                if ((bptr->icount == 0) || (bptr->flags == BBUNDEF))
                        continue;

Output:

Type ":help" for a list of available commands.
CL-USER(1): CL-USER(1): (compile nil (lambda () 42))
#<FUNCTION (LAMBDA ()) {94BA2C0}>
NIL
NIL
CL-USER(2):

Comment #4 by pm@complang.tuwien.ac.at on 2008-03-21 22:43:34

However, it needs to be investigated whether other code relies on predecessorcount being
-1 for exh blocks. After a grep on the source base, I strongly doubt that it will break
anything.

Comment #5 by twisti@complang.tuwien.ac.at on 2008-03-22 11:03:05

Thanks.  Can you assign the bug to you and close it?

Comment #6 by pm@complang.tuwien.ac.at on 2008-03-22 14:48:01

With hg tip the same lisp code fails with an exception. With jamvm 1.5.1 + the same
classpath fails with the same exception, so it's probably not related to cacao.

CL-USER(1): (compile nil (lambda () 42))
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
   at java.lang.String.charAt(String.java:625)
   at java.math.BigInteger.<init>(BigInteger.java:181)
   at org.armedbear.lisp.Bignum.<init>(Bignum.java:42)
...

Fixed in 7985. Closing.

Comment #7 by twisti@complang.tuwien.ac.at on 2008-03-25 09:22:56

For me it works with GNU Classpath 0.96.1 on x86_64:

$ cacao -jar abcl-0.0.9.1p.jar
Armed Bear Common Lisp 0.0.9.1+
Java 1.5.0 GNU Classpath
CACAO
Low-level initialization completed in 0.591 seconds.
Startup completed in 28.792 seconds.
Type ":help" for a list of available commands.
CL-USER(1): (compile nil (lambda () 42))
#<FUNCTION (LAMBDA ()) {38563C0}>
NIL
NIL
CL-USER(2):

With OpenJDK as class library it's hell-a-lot faster:

$ cacao -jar abcl-0.0.9.1p.jar
Armed Bear Common Lisp 0.0.9.1+
Java 1.6.0 Sun Microsystems Inc.
CACAO
Low-level initialization completed in 0.545 seconds.
Startup completed in 2.94 seconds.
Type ":help" for a list of available commands.
CL-USER(1): (compile nil (lambda () 42))
#<FUNCTION (LAMBDA ()) {2EB1FC0}>
NIL
NIL
CL-USER(2):