Status fields:
creation_ts: | 2008-03-04 23:29 |
---|---|
component: | jit |
version: | default branch |
rep_platform: | i386 |
op_sys: | Linux |
bug_status: | RESOLVED |
resolution: | FIXED |
reporter: | glegris-bugzilla@thenesis.org |
While trying to start Opera Mini 4 with MIDPath (SVN revision 216) a VerifyError occurred at some point in the obfuscated code. This problem doesn't occur with JamVM or the Sun VM. Steps to reproduce the problem ------------------------------ 1) Load the debug package : > wget http://midpath.thenesis.org/downloads/midpath-verifyerror-debug-040308.tar.gz > tar -zxvf midpath-verifyerror-debug-040308.tar.gz 2) Load Opera Mini 4.0.10406: > wget http://mini.opera.com/global/opera-mini-4.0.10406-advanced-int.jar 3) Start the script: > ./MIDPath-cacao-debug.sh 4) Add the breakpoint: (gdb) handle SIGILL SIGSEGV SIGPWR SIGXCPU nostop noprint (gdb) break exceptions_throw_verifyerror (gdb) run Result ------ Breakpoint 2, exceptions_throw_verifyerror (m=0x8b132a4, message=0xb7d97120 "Local variable type mismatch") at exceptions.c:1208 1208 if (m != NULL) (gdb) bt #0 exceptions_throw_verifyerror (m=0x8b132a4, message=0xb7d97120 "Local variable type mismatch") at exceptions.c:1208 #1 0xb7d73117 in typecheck (jd=0x862b698) at src/vm/jit/verify/icmds.c:566 #2 0xb7d6091a in jit_compile_intern (jd=0x862b698) at jit.c:699 #3 0xb7d6104b in jit_compile (m=0x8b132a4) at jit.c:414 #4 0xb7d611f2 in jit_compile_handle (m=0x8b132a4, pv=0xb67a2018, ra=0xb67a334b, mptr=0xb680dfd0) at jit.c:1061 #5 0xb7d3f6af in signal_handle (type=9, val=-1233068080, pv=0xb680dfd0, sp=0xb72ded40, ra=0xb67a334b, xpc=0xb67a3349, context=0xb72dea4c) at signal.c:342 #6 0xb7d6068b in md_signal_handler_sigsegv (sig=11, siginfo=0xb72de9cc, _p=0xb72dea4c) at md-os.c:137 #7 <signal handler called> #8 0xb680dfd0 in ?? () #9 0xb67a334b in ?? () #10 0x08143e10 in ?? () #11 0x081f81c0 in ?? () #12 0x0811ff80 in ?? () #13 0xb7f198c5 in pthread_getspecific () from /lib/i686/cmov/libpthread.so.0 Previous frame inner to this frame (corrupt stack?) (gdb) f 2 #2 0xb7d6091a in jit_compile_intern (jd=0x862b698) at jit.c:699 699 if (!typecheck(jd)) { (gdb) call show_method(jd, 2) d.Code(Ljavax/microedition/lcdui/Graphics;)Z PRIVATE (mono) (impl) (see the attached file for the full trace)
Created an attachment (id=33) Full trace
SVN revision 216? Are you sure? Edwin, could you take a look at this one?
I tried to download the "debug package", but it did not work: wget http://midpath.thenesis.org/downloads/midpath-verifyerror-debug-040308.tar.gz --21:27:54-- http://midpath.thenesis.org/downloads/midpath-verifyerror- debug-040308.tar.gz => `midpath-verifyerror-debug-040308.tar.gz' Resolving midpath.thenesis.org... 82.121.44.250 Connecting to midpath.thenesis.org|82.121.44.250|:80... failed: Connection refused. -Edwin
(In reply to comment #3) > I tried to download the "debug package", but it did not work: > > wget > http://midpath.thenesis.org/downloads/midpath-verifyerror-debug-040308.tar.gz > --21:27:54-- > http://midpath.thenesis.org/downloads/midpath-verifyerror-debug-040308.tar.gz > => `midpath-verifyerror-debug-040308.tar.gz' > Resolving midpath.thenesis.org... 82.121.44.250 > Connecting to midpath.thenesis.org|82.121.44.250|:80... failed: Connection > refused. > > -Edwin > Sorry for that. The web server was down a few hours yesterday... It should work now. Guillaume
I found the bug and it is a rather nasty one: The problem is bytecode like this sequence: aload_0 aload_0 arraylength istore_0 astore_1 The bytecode is legal and the local variables should have the types (0=INT,1=ADR) afterwards. CACAO, however, infers (0=INT,1=void). The problem is in the handling of the istore_0. As javalocal 0 is used for both INT and ADR types, it is split into two CACAO variables. The javalocal to CACAO mapping looks like this: javalocal 0 as INT -> CACAO local Li0 javalocal 0 as ADR -> CACAO local La1 javalocal 1 as ADR -> CACAO local La2 When istore_0 writes Li0, the variable La1 must be marked as invalidated (type void), because it is the same javalocal (index 0). This is done by typecheck_invalidate_locals. The problem is that at that time a copy of La1 is still on the "stack". As the stack has already been eliminated, there is no separate variable for the stack slot, so the "stack slot" is invalidated, too. The following astore copies the invalidated La1 to La2, making it "void". When one of the following blocks then loads La2, a verifier error is signalled. The actual bug seems to be in stack_analyse. It should create a temporary variable for the destination of the first aload_0, I think, to avoid the conflict with the istore_0. I have to think about that some more, as it has been a long time since I worked on stack_analyse. -Edwin
BTW, Guillaume, thanks for this excellent bug report. :) Such a good recipe for reproduction is very rare indeed. I think this bug was introduced with the variable renaming in stack_analyse. In particular, the following conflict check which had been correct up to this point, became insufficient because of variable renaming: stack.c:3267: if ((copy->varkind == LOCALVAR) && (copy->varnum == varindex)) The check can miss conflicts because the same javalocal is mapped to different "varnum"s if it is used for multiple types. One could say that the check is correct, as there is no conflict of _CACAO_ variables, BUT: Register allocation assumes that variables corresponding to the same javalocal can be coalesced without doing its own conflict checks! (At least it was this way when I worked on these parts of CACAO.) So the verifier is correct in reporting the error as otherwise an invalid allocation could be made. - Thus we must fix the conflict check. I'll try to prepare a patch. -Edwin
Created an attachment (id=34) trial patch for checking conflicts using the javaindex Guillaume, could you please try the attached patch? @twisti: Please do not commit as is. If we want to check conflicts this way, I will put the reverselocalmap into jd, so the verifier can reuse it instead of building its own. -Edwin
OK, I'll stay tuned. Do you still have problems with commit access?
(In reply to comment #7) > Created an attachment (id=34) [details] > trial patch for checking conflicts using the javaindex > > Guillaume, could you please try the attached patch? > > @twisti: Please do not commit as is. If we want to check > conflicts this way, I will put the reverselocalmap into jd, > so the verifier can reuse it instead of building its own. > > -Edwin > It works fine with the patch now ! Guillaume
Fixed with http://mips.complang.tuwien.ac.at/hg/cacao/rev/08444c22b833
date: | 2008-03-04 23:33 |
---|---|
desc: | Full trace |
type: | text/plain |
download: | bug-obfscated_classes-verifyerror.txt |
date: | 2008-03-16 18:11 |
---|---|
desc: | trial patch for checking conflicts using the javaindex |
type: | text/plain |
download: | check_javaindex_conflicts.patch |