Skip to content

fix 'Invalid array access' on 32bit linux #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

fix 'Invalid array access' on 32bit linux #39

wants to merge 1 commit into from

Conversation

sharow
Copy link
Contributor

@sharow sharow commented Oct 10, 2014

Issue

$ cat test.nml
 a = $array(1,3,"test");
 $print(a[0]);
 $print(a[1]);
 $print(a[2]);

$ nekoc test.nml
$ neko test.n
13test%
$
$ cat Main.hx
class Main {
    public static function main() {
        var a = [0, 1, 2];
        trace(a);
        trace(a[0]);
        trace("OK!");
    }
}

$ haxe -main Main -neko Main.n
$ neko Main.n
Main.hx:4: [0,1,2]
Called from ? line 1
Called from Array.hx line 291
Uncaught exception - Invalid array access
$

this known as haxelib-issue on 32bit-linux (but not haxelib issue)

$ haxelib
Called from ? line 1
Called from tools/haxelib/Main.hx line 1257
Called from Array.hx line 291
Uncaught exception - Invalid array access

this is only happen built by gcc on i686-linux. clang version works fine.

Cause

EXTERN value val_field( value _o, field id ) {
    value *f;
    // WARNING : we can't change the value on the stack
    // since it will be reused by the JIT (when compiled with GCC)
    vobject *o = (vobject *)_o;
    do {
        f = otable_find(&o->table,id);
        if( f != NULL )
            return *f;
        o = o->proto;
    } while( o );
    return val_null;
}
  • _o is borrowed from caller (reuse by the JIT comment say)
  • but _o is still mutable value
  • vobject *o = (vobject *)_o is just alias-name for compiler, dosen't help
from  objdump -D ./libneko.so | grep -A 55 "<neko_val_field>:"

00010690 <neko_val_field>:
   10690:   55                      push   %ebp
   10691:   57                      push   %edi
   10692:   56                      push   %esi
   10693:   53                      push   %ebx
   10694:   8b 6c 24 18             mov    0x18(%esp),%ebp
   10698:   8b 44 24 14             mov    0x14(%esp),%eax
   1069c:   e8 1f 26 ff ff          call   2cc0 <__x86.get_pc_thunk.bx>
   106a1:   81 c3 3f 6d 01 00       add    $0x16d3f,%ebx
   106a7:   89 f6                   mov    %esi,%esi
   106a9:   8d bc 27 00 00 00 00    lea    0x0(%edi,%eiz,1),%edi
   106b0:   8b 50 04                mov    0x4(%eax),%edx
   106b3:   8b 78 08                mov    0x8(%eax),%edi
   106b6:   85 d2                   test   %edx,%edx
   106b8:   7e 21                   jle    106db <neko_val_field+0x4b>
   106ba:   31 c9                   xor    %ecx,%ecx
   106bc:   eb 09                   jmp    106c7 <neko_val_field+0x37>
   106be:   66 90                   xchg   %ax,%ax
   106c0:   8d 48 01                lea    0x1(%eax),%ecx
   106c3:   39 d1                   cmp    %edx,%ecx
   106c5:   7d 14                   jge    106db <neko_val_field+0x4b>
   106c7:   8d 04 11                lea    (%ecx,%edx,1),%eax
   106ca:   d1 f8                   sar    %eax
   106cc:   8d 34 c7                lea    (%edi,%eax,8),%esi
   106cf:   3b 2e                   cmp    (%esi),%ebp
   106d1:   7f ed                   jg     106c0 <neko_val_field+0x30>
   106d3:   7d 2b                   jge    10700 <neko_val_field+0x70>
   106d5:   89 c2                   mov    %eax,%edx
   106d7:   39 d1                   cmp    %edx,%ecx
   106d9:   7c ec                   jl     106c7 <neko_val_field+0x37>
   106db:   8b 44 24 14             mov    0x14(%esp),%eax    ;; 0x14(%esp) is _o (on the stack)
   106df:   8b 40 0c                mov    0xc(%eax),%eax     ;; eax = _o->proto
   106e2:   85 c0                   test   %eax,%eax          ;; test for while (eax)
   106e4:   89 44 24 14             mov    %eax,0x14(%esp)    ;; << write to 0x14(%esp) !!!!!
   106e8:   75 c6                   jne    106b0 <neko_val_field+0x20>
   106ea:   8d 83 48 01 00 00       lea    0x148(%ebx),%eax
   106f0:   5b                      pop    %ebx
   106f1:   5e                      pop    %esi
   106f2:   8b 00                   mov    (%eax),%eax
   106f4:   5f                      pop    %edi
   106f5:   5d                      pop    %ebp
   106f6:   c3                      ret
   106f7:   89 f6                   mov    %esi,%esi
   106f9:   8d bc 27 00 00 00 00    lea    0x0(%edi,%eiz,1),%edi
   10700:   5b                      pop    %ebx
   10701:   8b 46 04                mov    0x4(%esi),%eax
   10704:   5e                      pop    %esi
   10705:   5f                      pop    %edi
   10706:   5d                      pop    %ebp
   10707:   c3                      ret
   10708:   90                      nop
   10709:   8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi

and, solution is

  • use const

Related link

these will be fixed.

@ncannasse
Copy link
Member

Thank you for the investigation. However I wonder if we need to either change this in the API declaration or in the JIT itself : maybe we should not make assumption that the arguments passed into the stack are not modified by the called function, since there might be other cases of this as well.

What do you think ?

@sharow
Copy link
Contributor Author

sharow commented Oct 10, 2014

Thank you for reply.

Totally agree. Follow the call-by-value rule is right way. I am looking forward to the next stable release!

@sharow sharow closed this Oct 10, 2014
@sharow sharow deleted the fix-linux32-invalid-array-access2 branch October 12, 2014 03:41
@sharow sharow mentioned this pull request May 20, 2015
@andyli andyli mentioned this pull request Sep 18, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants