Skip to main content

jit on arm 920t crashed with signal 4

15 replies [Last post]
lua2010
Offline
Joined: 2006-11-16
Points: 0

Hi all,

my application (sending an email via javamail-API) crashed:
$ /root/cvm_1_1/bin/cvm -cp mail.jar demo.smtpsend
Process #676 received signal 4, suspending

Starting the cvm with the option -Xjit:compile=none it works.

Has anyone similar problems? Any Solution?

I use the linux kernel 2.4.26
and the following compile options for the cvm (CDC HI/FP (1.1.1_01-b31):
CVM_FORCE_HARD_FLOAT = true
CC_ARCH_FLAGS = -mcpu920t
USE_GCC2 ?= false
J2ME_CLASSLIB=foundation

Thanks

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
xyzzy
Offline
Joined: 2006-08-30
Points: 0

> It sounds like your compiler is targettig ARMv3 by
> default. Although this will probably still work with
> CVM/CDC, I think it would probably fail to run on a
> true ARMv3 device because I believe at the very least
> our JIT depends on ARMv4 instructions. Since you have
> an ARMv4 device, it will probably work ok.
>
> In any case, adding __ARM_ARCH_3__ to the list of
> #defines we check for would probably be a good idea.
>
> Chris Plummer

If including both the ARMv4 and ARMv5 versions of the code doesn't take up too much space, we could possibly detect ARMv5 at runtime and try to have a single ARMv4 binary that supports both. Or we could at least have a sanity check to detect cases like this early and print out a meaningful diagnostic message.

Dean

jiangli_zhou
Offline
Joined: 2006-10-16
Points: 0

Chris is definitely right. We have a faster version of Idiv, which uses 'clz' for ARMv5 and later. Note in iai_opt_config.h, there are more than one #if !defined(__ARM_ARCH_4__). You should check all of them.

jiangli_zhou
Offline
Joined: 2006-10-16
Points: 0

Is it possible that you can run it from gdb?

I forgot handleSegv() only handles SIGSEGV. Sorry. The SIGILL is handled by crash() in src/linux/javavm/runtime/sync_md.c. Try to see if you could get the pc from there.

Good luck.

lua2010
Offline
Joined: 2006-11-16
Points: 0

I've registered SIGILL in linuxSegvHandlerInit() to handle SIGILL in handleSegv(). When running demo.stmpsend, I get the following output now

arm_pc=0x2b250d24 arm_lr=0x2b25283c arm_ip=0x740cccbfi arm_sp=0x7ffffc58 arm_fp=0x2acbb1dc

java.lang.ExceptionInInitializerError
at java.lang.Class.runStaticInitializers(Class.java:1631)
at demo.smtpsend.main(smtpsend.java:163)
at java.lang.reflect.Method.invoke(Method.java:316)
at sun.misc.CVM.runMain(CVM.java:478)
Caused by: java.lang.NullPointerException
at java.util.Hashtable.put(Compiled Method)(Hashtable.java:413)
at sun.text.resources.DateFormatZoneData.loadLookup(DateFormatZoneData.java:163)
at sun.text.resources.DateFormatZoneData.getKeys(DateFormatZoneData.java:115)
at sun.text.resources.DateFormatZoneData.getKeys(DateFormatZoneData.java:120)
at java.text.DateFormatSymbols.loadZoneStrings(DateFormatSymbols.java:466)
at java.text.DateFormatSymbols.initializeData(DateFormatSymbols.java:506)
at java.text.DateFormatSymbols.(DateFormatSymbols.java:120)
at java.text.SimpleDateFormat.(SimpleDateFormat.java:459)
at javax.mail.internet.MailDateFormat.(MailDateFormat.java:108)
at javax.mail.internet.MimeMessage.(MimeMessage.java:132)
at java.lang.Class.runStaticInitializers(Class.java:1610)
... 3 more

I can't find compiled code for the pc. Maybe the trace around will help. It's the compiled code for java.util.Hashtable.put

0x2b252828 152: bic a1, v3, #-2147483648
0x2b25282c 156: ldr lr, [rJFP, #-40] @ Java local cell # 3
0x2b252830 160: ldr a2, [lr, #+8] @ arraylength
0x2b252834 164: str a2, [rJFP, #+36] @ spill Java temp cell # 3
0x2b252838 168: bl PC=(-5984) @ call CVMCCMruntimeIRem
0x2b25283c 172: ldr v8, [rJFP, #+36] @ Java temp cell # 3
0x2b252840 176: cmp v8, a1 LSL #0
0x2b252844 180: blls PC=(-14128) @ ArrayIndexOutOfBounds check
@ Do load(arrayObj, index) (elem type=L):

Is there a problem in CVMCCMruntimeIRem ?

cjplummer
Offline
Joined: 2006-10-16
Points: 0

The PC is likely in CVMCCMruntimeIRem. Is there a reason you can't "x /i arm_pc" from GDB to find the instruction that crashed?

The only problem I can think of with CVMCCMruntimeIRem is that it thinks you are on an ARMv5 or better platform, but you are not. This will result in it making use of CLZ, which would produce a SIGILL on ARMv4.

You said you are on an ARM 920t, which is ARMv4. Note the following code in src/arm/javavm/include/iai_opt_config.h

/*
* Faster version of CVMCCMruntimeIDiv. Uses CLZ. Needs ARM5 or later.
*/
#if !defined(__ARM_ARCH_4__) && !defined(__ARM_ARCH_4T__)
#define IAI_IDIV
#endif

This is the best way I could find for determining if ARMv5 or better is available. Perhaps your platform is generating some other ARCH define for v4 that is not captured above. To find which define your compiler generates, do the following:

$ touch /tmp/test.c
$ gcc -E -dM /tmp/test.c | grep ARCH

Of course gcc should be your cross gcc, not the "gcc" on the path.

lua2010
Offline
Joined: 2006-11-16
Points: 0

That's it!!

the result is:
#define __ARM_ARCH_3__ 1

Without the optimization demo.sendsmtp works with jit!

Now I must still find out why gcc uses__ARM_ARCH_3__

Many thanks!

cjplummer
Offline
Joined: 2006-10-16
Points: 0

It sounds like your compiler is targettig ARMv3 by default. Although this will probably still work with CVM/CDC, I think it would probably fail to run on a true ARMv3 device because I believe at the very least our JIT depends on ARMv4 instructions. Since you have an ARMv4 device, it will probably work ok.

In any case, adding __ARM_ARCH_3__ to the list of #defines we check for would probably be a good idea.

Chris Plummer

cjplummer
Offline
Joined: 2006-10-16
Points: 0

Try building with -mcpu=arm920t.

Chris Plummer

lua2010
Offline
Joined: 2006-11-16
Points: 0

Is there, perhaps, another problem?

With
"gcc -E -dM -mpcu=arm920t /tmp/test.c | grep ARCH"
I get "__ARM_ARCH_4T__ 1"
I use -mpcu=arm920t all the time to build the cvm.

For the test (which was successful) I have commented out the following line
#define IAI_IDIV

Are the defines in the header not recognized properly?

cjplummer
Offline
Joined: 2006-10-16
Points: 0

Since your gcc defaults to __ARM_ARCH_3__, you probably need to add -mcpu=arm920t to ASM_ARCH_FLAGS also, not just CC_ARCH_FLAGS, although it's interesting that it would even assemble a CLZ instruction when generating code for __ARM_ARCH_3__.

cjplummer
Offline
Joined: 2006-10-16
Points: 0

Just a warning, we haven't really dealt with a hard float linux/ARM targets. Once we played around with forcing hard float on an old Netwinder (thus the CVM_FORCE_HARD_FLOAT flag), but that was years ago and I recall it producing many tck failures.

Which Linux distro are you using? Do you know the calling conventions (APCS or AAPCS)? Is it using VFP or FPA floating point?

lua2010
Offline
Joined: 2006-11-16
Points: 0

Hi,

I'm using a SBC based on the Cirrus EP9302 ARM9 CPU which comes with the MaverickCrunchâ„¢ coprocessor. The coprocessor uses IEEE-754, though uses a different instruction set to VFP.
http://www.cirrus.com/en/products/pro/detail/P1066.html

The kernel comes from
http://www.arm.linux.org.uk/

I build the cvm on SUSE-Linux with GNU toolchain (gcc 3.3.4, glibc 2.3.2).

I've tried with CVM_FORCE_HARD_FLOAT=false (I don't need the hard float feature). The behavior is the same with demo.smtpsend. But running -cp testclasses.zp Test, i get now this two errors:
*TEST FAILURE: FloatMIN (the two-way transformation)
*TEST FAILURE: FloatMAX (the two-way transformation)

cjplummer
Offline
Joined: 2006-10-16
Points: 0

I think the problem is that you have a platform that defaults to using hard float VFP, and this is something we haven't really worked with before. All the CVM_FORCE_HARD_FLOAT stuff you see in makefiles and in the source was done as part of a half-hearted experiment to see if we could get hard float working on a Netwinder (which had no FPU, but did have FP emulation in the kernal).

The SIGILL is probably because of code in invokeNative_arm.s:

#ifdef CVM_FORCE_HARD_FLOAT
LABEL(ret_f32)
stfs f0,[a4]
mov a1,#1 /* 1 indicates single-word return */
LDMFD sp!, {SAVESET, lr}
BR_REG(lr)

LABEL(ret_f64)
stfd f0,[a4]
mov a1,#2 /* 2 indicates double-word return */
LDMFD sp!, {SAVESET, lr}
BR_REG(lr)
#endif

This code was written before VFP and is most likely not compatible. VFP hard float support is something we plan on starting work on very soon now, but in the mean time you (or some other community volunteer) will need to try to work through problems like this if you want VFP hard float support. Note that VFP soft float support does work.

Chris Plummer

jiangli_zhou
Offline
Joined: 2006-10-16
Points: 0

Signal 4 is for illegal instruction. It must come from JIT'ed code or the glue code since -Xjit:compile=none (no compilation) runs fine. Try enabling the codegen tracing by using -Xjit:trace=codegen. That dumps all compiled code. If you can find the 'pc' of the illegal instruction, then you can find out what instruction it is using the tracing output. If gdb is available, I suggest you attach it to gdb. Otherwise, you can try to print out the 'pc' in handleSegv() (in src/linux-arm/javavm/runtime/segvhandler_arch.c).

Jiangli Zhou

lua2010
Offline
Joined: 2006-11-16
Points: 0

Hi,

I get the trace. But i don't get the pc: gdb can't attach to the suspendig process. I'm logging the pc in handleSegv(), but it seems that the handler isn't called.

Here's the end of the trace.

JS: ATTEMPTING TO COMPILE java.util.Hashtable.put(Ljava/lang/Object;Ljava/lang/Object; )Ljava/lang/Object;
JS: COMPILING java.util.Hashtable.put(Ljava/lang/Object;Ljava/lang/Object; )Ljava/lang/Object;
NUM BARRIER BYTES = 80
NUM VIRTUAL INLINE BYTES = 96
NUM LARGE OPCODE BYTES = 44
NUM MAIN LINE INSTRUCTION BYTES ESTIMATE = 1208
ESTIMATED BUFFER SIZE = 1624
CODE BUFFER ADDRESS = 0x2b2528d8
PC MAP TABLE ADDRESS = 0x2b2528e0
INLINING INFO ADDRESS = 0x2b252910
GC CHECK PCS ADDRESS = 0x2b252938
CODE ENTRY ADDRESS = 0x2b252960

.....
.....

0x2b252c3c 732: str v3, [rJSP], #+4
@ Invoke a method w/ a 32bit return type
0x2b252c40 736: mov a1, v4 LSL #0
0x2b252c44 740: mov lr, pc LSL #0 @ setup return address
0x2b252c48 744: ldr pc, [a1, #+0] @ call method through mb
@ Captured a stackmap here.
0x2b252c4c 748: ldr v3, [rJSP, #-4]!
@ Processing DEFINE(0) reg(6): in correct register
@ Loading DEFINE(0) register(6): in correct register
0x2b252c50 752: b PC=(152) @ branch to block L6
@ Initial Temp REF set is
L9: 756: @ entry point for branches
:::::Fixed instruction at 344 to reference 756
@ MAP_PC idepth=0 javaPc=60 compiledPc=756
0x2b252c54 756: str v3, [rJSP], #+4
0x2b252c58 760: str v4, [rJSP], #+4
@ Invoke a method w/ a 32bit return type
0x2b252c5c 764: mov a1, v5 LSL #0
0x2b252c60 768: mov lr, pc LSL #0 @ setup return address
0x2b252c64 772: ldr pc, [a1, #+0] @ call method through mb
@ Captured a stackmap here.
0x2b252c68 776: ldr v3, [rJSP, #-4]!
@ Processing DEFINE(0) reg(6): in correct register
@ Loading DEFINE(0) register(6): in correct register
0x2b252c6c 780: b PC=(376) @ branch to block L8
0x2b252c70 784: .word 2289624 @ cb java.util.Hashtable$Entry
:::::Fixed instruction at 556 to reference 784
0x2b252c74 788: .word 1991479 @ cardTableVirtualBase
:::::Fixed instruction at 616 to reference 788
:::::Fixed instruction at 420 to reference 788
0x2b252c78 792: .word 3085856 @ mb java.lang.Object.equals(Ljava/lang/Object; )Z
:::::Fixed instruction at 336 to reference 792
0x2b252c7c 796: .word 3086868 @ mb java.lang.String.hashCode()I
:::::Fixed instruction at 128 to reference 796
0x2b252c80 800: .word 3308024 @ mb java.lang.NullPointerException.()V
:::::Fixed instruction at 80 to reference 800
0x2b252c84 804: .word 2815372 @ cb java.lang.NullPointerException
:::::Fixed instruction at 56 to reference 804
>>>>>>>>>Push Code Buffer to PC = 4 (0x2b252964) >>>>>>>>
@ Capacity is 34 word(s)
0x2b252964 4: add a2, rJSP, #124
<<<<<<<< >>>>>>>>>Push Code Buffer to PC = 32 (0x2b252980) >>>>>>>>
@ spillSize is 4 word(s), add to JFP+24
0x2b252980 32: add rJSP, rJFP, #40
<<<<<<<< Process #749 received signal 4, suspending