nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
107.66k stars 29.63k forks source link

Getting 'illegal instruction' error on armv6 #283

Closed Cydox closed 9 years ago

Cydox commented 9 years ago

I built io.js with the change #282 on armv6. When running io.js i get an 'Illegal instruction' error. g++ and gcc are on version 4.8.3. There where no errors while building. I don´t know what other information i could give you. Just ask me for the information you need and i´ll post it.

bnoordhuis commented 9 years ago

There was an rpi thread on v8-users recently. I don't know if you were involved but it lists a few things you can try. If nothing else, can you post the output of backtrace and disassemble from gdb?

Cydox commented 9 years ago

I saw another thread. I´m trying command line arguments from that one. But this will take some time since the Pi is slow(probably will take till tomorrow morning). When it works should I do a PR so it will print an error message if people don't use these options and add it to #282 ?

bnoordhuis commented 9 years ago

Yes, that would be great.

bnoordhuis commented 9 years ago

@Cydox How did it work?

fivdi commented 9 years ago

I remember having the 'illegal instruction' error on the Raspberry Pi after successfully compiling node v0.11.8 or v0.11.9 on the Pi itself. I think the issue may be related to the following code (from deps/v8/src/base/cpu.cc):

    // Unfortunately, it seems that certain ARMv6-based CPUs
    // report an incorrect architecture number of 7!
    //
    // See http://code.google.com/p/android/issues/detail?id=10812
    //
    // We try to correct this by looking at the 'elf_format'
    // field reported by the 'Processor' field, which is of the
    // form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
    // an ARMv6-one. For example, the Raspberry Pi is one popular
    // ARMv6 device that reports architecture 7.
    if (architecture_ == 7) {
      char* processor = cpu_info.ExtractField("Processor");
      if (HasListItem(processor, "(v6l)")) {
        architecture_ = 6;
      }
      delete[] processor;
    }

This code looks at the Processor field in file /proc/cpuinfo to see if it can find "(v6l)"

Everything works correctly on older versions of Raspbian with the following /proc/cpuinfo as the Processor field contains "(v6l)":

Processor   : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS    : 697.95
Features    : swp half thumb fastmult vfp edsp java tls 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xb76
CPU revision    : 7

Hardware    : BCM2708
Revision    : 0002
Serial      : 000000008a51a472

However, on newer versions of Raspbian "(v6l)" has been moved to the model name field, V8 doesn't find it, and assumes that the Pi has an ARMv7 processor:

processor   : 0
model name  : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS    : 2.00
Features    : swp half thumb fastmult vfp edsp java tls 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xb76
CPU revision    : 7

Hardware    : BCM2708
Revision    : 0002
Serial      : 000000008a51a472

Related issues: https://github.com/joyent/node/issues/7222 https://code.google.com/p/v8/issues/detail?id=3112

Cydox commented 9 years ago

This is really getting crazy now. An hour ago it the build on my Pi worked, but now i was giving it a second test but this time it gives me 'illegal instruction'. Runnig iojs --v8-options gives me

target arm v6 vfp3 hard ARMv7=1 VFP3=1 VFP32DREGS=1 NEON=0 SUDIV=0 UNALIGNED_ACCESSES=1 MOVW_MOVT_IMMEDIATE_LOADS=0 COHERENT_CACHE=0 USE_EABI_HARDFLOAT=1

so it is detecting armv7 again. @bnoordhuis should we try to change the code in cpu.cc? Or is it a problem because it is in v8?

Cydox commented 9 years ago

i think the reason why it didnt work is that (as stated in https://code.google.com/p/v8/issues/detail?id=3112) the option arm-version=6 I was using is not in this version of v8 but in a newer one. And in https://code.google.com/p/v8/issues/detail?id=3112 at the end there is a patch that looks like it should work(obviously I dont have enough experience with a code working on mutiple platforms). I´m gonna test the patch on my Pi and tell you wther it worked or not(and i´ll try more then once now before saying it works).

Cydox commented 9 years ago

I added this change to the Code:

if (architecture_ == 7) {
       std::cout << "7" << std::endl;
       char* processor;
       processor = cpu_info.ExtractField("Processor");
       if (HasListItem(processor, "(v6l)")) {
         architecture_ = 6;
       }
       processor = cpu_info.ExtractField("model name");
      if (HasListItem(processor, "(v6l)")) {
        std::cout << "6" << std::endl;
        architecture_ = 6;
      }
      delete[] processor;
    }
  }

I included iostream obviously and added the 'print' statements to see wether thoughs if statements got called('not the best debugging probably'). Both if statements were called. ´So the architectue_ should have been set to 6 just like it needs to. But the output is just:

# ./iojs
7
6
Illegal instruction

I only did a short make so i didn´t need to compile the whole thing again. Could this have an impact? I can´t think of anything else. iojs --v8-options returned that it is armv7 again.

Cydox commented 9 years ago

gdb backtrace and disassemble:

gdb ./iojs
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/pi/io.js/iojs...done.
(gdb) run
Starting program: /home/pi/io.js/iojs
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".

Program received signal SIGILL, Illegal instruction.
0x00378a60 in _armv7_neon_probe ()
(gdb) backtrace
#0  0x00378a60 in _armv7_neon_probe ()
#1  0x00232cc0 in OPENSSL_cpuid_setup ()
#2  0x008a71d4 in __libc_csu_init ()
#3  0xb6cc5228 in __libc_start_main () from /lib/arm-linux-gnueabihf/libc.so.6
#4  0x00233068 in _start ()
(gdb) dissasemble
Undefined command: "dissasemble".  Try "help".
(gdb) disassemble
Dump of assembler code for function _armv7_neon_probe:
=> 0x00378a60 <+0>:     vorr    q15, q15, q15
   0x00378a64 <+4>:     bx      lr
End of assembler dump.
indutny commented 9 years ago

@Cydox please type c and hit Enter key after seeing this openssl thing. It is the way the OpenSSL detects platform. It sets SIGILL handler and executes the assembly code.

Again, this could be ignored, please hit the c after it.

Cydox commented 9 years ago

like that?

(gdb) run
Starting program: /home/pi/io.js/iojs
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".

Program received signal SIGILL, Illegal instruction.
0x00378a60 in _armv7_neon_probe ()
(gdb) backtrace
#0  0x00378a60 in _armv7_neon_probe ()
#1  0x00232cc0 in OPENSSL_cpuid_setup ()
#2  0x008a71d4 in __libc_csu_init ()
#3  0xb6cc5228 in __libc_start_main () from /lib/arm-linux-gnueabihf/libc.so.6
#4  0x00233068 in _start ()
(gdb) c
Continuing.

Program received signal SIGILL, Illegal instruction.
0x00378a68 in _armv7_tick ()
indutny commented 9 years ago

What if you'll hit c again? ;)

Cydox commented 9 years ago

here are a bunch of ´em :D

 c
Continuing.

Program received signal SIGILL, Illegal instruction.
0x00378a68 in _armv7_tick ()
(gdb) c
Continuing.
[New Thread 0xb6cab450 (LWP 26581)]
[New Thread 0xb64ab450 (LWP 26582)]
[New Thread 0xb5cab450 (LWP 26583)]
[New Thread 0xb54ab450 (LWP 26584)]
7
6

Program received signal SIGILL, Illegal instruction.
0x539242c0 in ?? ()
(gdb) c
Continuing.
[Thread 0xb54ab450 (LWP 26584) exited]
[Thread 0xb5cab450 (LWP 26583) exited]
[Thread 0xb64ab450 (LWP 26582) exited]
[Thread 0xb6cab450 (LWP 26581) exited]

Program terminated with signal SIGILL, Illegal instruction.
The program no longer exists.
Cydox commented 9 years ago

Any new ideas on what fails here?

bnoordhuis commented 9 years ago

It's most likely the last SIGILL that we're interested in. If all else fails, turn on coredumps with ulimit -c and disassemble it in gdb afterwards: gdb /path/to/iojs /path/to/corefile, then disassemble. Maybe inspect info threads as well (help threads for more info, or ask if you have questions.)

silverwind commented 9 years ago

Is this any help?

GNU gdb (GDB) 7.8.2
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "armv6l-unknown-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from iojs...done.
(gdb) core core.iojs.1000.8e19a9713eb944d08076e926610092a7.20772.1421518688000000
[New LWP 20772]
[New LWP 20773]
[New LWP 20776]
[New LWP 20775]
[New LWP 20774]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Core was generated by `iojs'.
Program terminated with signal SIGILL, Illegal instruction.
#0  0x5b7242c0 in ?? ()
(gdb) disassemble
No function contains program counter for selected frame.
(gdb) info threads
  Id   Target Id         Frame
  5    Thread 0xb63df450 (LWP 20774) 0xb6d2c0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  4    Thread 0xb5bdf450 (LWP 20775) 0xb6d2c0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  3    Thread 0xb53df450 (LWP 20776) 0xb6d2c0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  2    Thread 0xb6bdf450 (LWP 20773) 0xb6d2c0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
* 1    Thread 0xb6f3d000 (LWP 20772) 0x5b7242c0 in ?? ()
(gdb)
silverwind commented 9 years ago

And here's thread 2:

(gdb) thread 2
[Switching to thread 2 (Thread 0xb6bdf450 (LWP 20773))]
#0  0xb6d2c0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
(gdb) disassemble
Dump of assembler code for function pthread_cond_wait@@GLIBC_2.4:
   0xb6d2bfb8 <+0>: push    {r4, r5, r6, r7, r8, r9, r10, r11, lr}
   0xb6d2bfbc <+4>: sub sp, sp, #68 ; 0x44
   0xb6d2bfc0 <+8>: ldr r3, [r0, #32]
   0xb6d2bfc4 <+12>:    mov r4, r0
   0xb6d2bfc8 <+16>:    cmn r3, #1
   0xb6d2bfcc <+20>:    str r1, [sp, #12]
   0xb6d2bfd0 <+24>:    beq 0xb6d2c1fc <pthread_cond_wait@@GLIBC_2.4+580>
   0xb6d2bfd4 <+28>:    mov r3, #1
   0xb6d2bfd8 <+32>:    mov r6, #0
   0xb6d2bfdc <+36>:    str r6, [sp, #48]   ; 0x30
   0xb6d2bfe0 <+40>:    ldrex   r2, [r4]
   0xb6d2bfe4 <+44>:    cmp r2, r6
   0xb6d2bfe8 <+48>:    bne 0xb6d2bffc <pthread_cond_wait@@GLIBC_2.4+68>
   0xb6d2bfec <+52>:    strex   r1, r3, [r4]
   0xb6d2bff0 <+56>:    cmp r1, #0
   0xb6d2bff4 <+60>:    bne 0xb6d2bfe0 <pthread_cond_wait@@GLIBC_2.4+40>
   0xb6d2bff8 <+64>:    mcr 15, 0, r0, cr7, cr10, {5}
   0xb6d2bffc <+68>:    movne   r3, r6
   0xb6d2c000 <+72>:    bne 0xb6d2c1c8 <pthread_cond_wait@@GLIBC_2.4+528>
   0xb6d2c004 <+76>:    ldr r0, [sp, #12]
   0xb6d2c008 <+80>:    mov r1, #0
   0xb6d2c00c <+84>:    bl  0xb6d2a104 <__pthread_mutex_unlock_usercnt>
   0xb6d2c010 <+88>:    subs    r12, r0, #0
   0xb6d2c014 <+92>:    bne 0xb6d2c238 <pthread_cond_wait@@GLIBC_2.4+640>
   0xb6d2c018 <+96>:    ldrd    r2, [r4, #8]
   0xb6d2c01c <+100>:   ldr r12, [r4, #32]
   0xb6d2c020 <+104>:   ldr r1, [r4, #36]   ; 0x24
   0xb6d2c024 <+108>:   adds    r8, r2, #1
   0xb6d2c028 <+112>:   adc r9, r3, #0
   0xb6d2c02c <+116>:   cmn r12, #1
   0xb6d2c030 <+120>:   add r3, r1, #2
---Type <return> to continue, or q <return> to quit---
   0xb6d2c034 <+124>:   ldr r0, [r4, #4]
   0xb6d2c038 <+128>:   str r3, [r4, #36]   ; 0x24
   0xb6d2c03c <+132>:   ldrne   r3, [sp, #12]
   0xb6d2c040 <+136>:   add r0, r0, #1
   0xb6d2c044 <+140>:   strne   r3, [r4, #32]
   0xb6d2c048 <+144>:   ldr r1, [pc, #604]  ; 0xb6d2c2ac <pthread_cond_wait@@GLIBC_2.4+756>
   0xb6d2c04c <+148>:   add r3, sp, #32
   0xb6d2c050 <+152>:   str r0, [r4, #4]
   0xb6d2c054 <+156>:   str r3, [sp, #20]
   0xb6d2c058 <+160>:   mov r0, r3
   0xb6d2c05c <+164>:   ldr r3, [sp, #12]
   0xb6d2c060 <+168>:   strd    r8, [r4, #8]
   0xb6d2c064 <+172>:   add r2, sp, #48 ; 0x30
   0xb6d2c068 <+176>:   add r1, pc, r1
   0xb6d2c06c <+180>:   str r3, [sp, #56]   ; 0x38
   0xb6d2c070 <+184>:   str r4, [sp, #52]   ; 0x34
   0xb6d2c074 <+188>:   bl  0xb6d2e9ac <_pthread_cleanup_push>
   0xb6d2c078 <+192>:   ldrd    r2, [r4, #16]
   0xb6d2c07c <+196>:   eor r10, r6, #128   ; 0x80
   0xb6d2c080 <+200>:   add r9, r4, #4
   0xb6d2c084 <+204>:   strd    r2, [sp]
   0xb6d2c088 <+208>:   mov r5, #0
   0xb6d2c08c <+212>:   add r2, sp, #28
   0xb6d2c090 <+216>:   ldr r3, [r4, #40]   ; 0x28
   0xb6d2c094 <+220>:   mov r8, #1
   0xb6d2c098 <+224>:   str r2, [sp, #8]
   0xb6d2c09c <+228>:   eor r2, r6, #129    ; 0x81
   0xb6d2c0a0 <+232>:   str r2, [sp, #16]
   0xb6d2c0a4 <+236>:   str r3, [sp, #60]   ; 0x3c
   0xb6d2c0a8 <+240>:   ldr r11, [r4, #4]
   0xb6d2c0ac <+244>:   mcr 15, 0, r0, cr7, cr10, {5}
   0xb6d2c0b0 <+248>:   ldrex   r3, [r4]
---Type <return> to continue, or q <return> to quit---
   0xb6d2c0b4 <+252>:   strex   r2, r5, [r4]
   0xb6d2c0b8 <+256>:   cmp r2, #0
   0xb6d2c0bc <+260>:   bne 0xb6d2c0b0 <pthread_cond_wait@@GLIBC_2.4+248>
   0xb6d2c0c0 <+264>:   cmp r3, #1
   0xb6d2c0c4 <+268>:   bgt 0xb6d2c1e0 <pthread_cond_wait@@GLIBC_2.4+552>
   0xb6d2c0c8 <+272>:   bl  0xb6d2edcc <__pthread_enable_asynccancel>
   0xb6d2c0cc <+276>:   mov r7, #240    ; 0xf0
   0xb6d2c0d0 <+280>:   mov r2, r11
   0xb6d2c0d4 <+284>:   mov r1, r10
   0xb6d2c0d8 <+288>:   mov r3, #0
   0xb6d2c0dc <+292>:   str r0, [sp, #48]   ; 0x30
   0xb6d2c0e0 <+296>:   mov r0, r9
=> 0xb6d2c0e4 <+300>:   svc 0x00000000
   0xb6d2c0e8 <+304>:   ldr r0, [sp, #48]   ; 0x30
   0xb6d2c0ec <+308>:   bl  0xb6d2ee8c <__pthread_disable_asynccancel>
   0xb6d2c0f0 <+312>:   str r5, [sp, #28]
   0xb6d2c0f4 <+316>:   ldrex   r3, [r4]
   0xb6d2c0f8 <+320>:   cmp r3, #0
   0xb6d2c0fc <+324>:   bne 0xb6d2c110 <pthread_cond_wait@@GLIBC_2.4+344>
   0xb6d2c100 <+328>:   strex   r2, r8, [r4]
   0xb6d2c104 <+332>:   cmp r2, #0
   0xb6d2c108 <+336>:   bne 0xb6d2c0f4 <pthread_cond_wait@@GLIBC_2.4+316>
   0xb6d2c10c <+340>:   mcr 15, 0, r0, cr7, cr10, {5}
   0xb6d2c110 <+344>:   mov r0, r4
   0xb6d2c114 <+348>:   mov r1, r6
   0xb6d2c118 <+352>:   beq 0xb6d2c128 <pthread_cond_wait@@GLIBC_2.4+368>
   0xb6d2c11c <+356>:   ldr r2, [sp, #8]
   0xb6d2c120 <+360>:   str r3, [r2]
   0xb6d2c124 <+364>:   bl  0xb6d2ef88 <__lll_lock_wait>
   0xb6d2c128 <+368>:   ldr r2, [sp, #60]   ; 0x3c
   0xb6d2c12c <+372>:   ldr r3, [r4, #40]   ; 0x28
   0xb6d2c130 <+376>:   cmp r2, r3
---Type <return> to continue, or q <return> to quit---
   0xb6d2c134 <+380>:   bne 0xb6d2c168 <pthread_cond_wait@@GLIBC_2.4+432>
   0xb6d2c138 <+384>:   ldrd    r2, [r4, #16]
   0xb6d2c13c <+388>:   ldrd    r0, [sp]
   0xb6d2c140 <+392>:   cmp r3, r1
   0xb6d2c144 <+396>:   cmpeq   r2, r0
   0xb6d2c148 <+400>:   beq 0xb6d2c0a8 <pthread_cond_wait@@GLIBC_2.4+240>
   0xb6d2c14c <+404>:   ldrd    r0, [r4, #24]
   0xb6d2c150 <+408>:   cmp r1, r3
   0xb6d2c154 <+412>:   cmpeq   r0, r2
   0xb6d2c158 <+416>:   beq 0xb6d2c0a8 <pthread_cond_wait@@GLIBC_2.4+240>
   0xb6d2c15c <+420>:   adds    r0, r0, #1
   0xb6d2c160 <+424>:   adc r1, r1, #0
   0xb6d2c164 <+428>:   strd    r0, [r4, #24]
   0xb6d2c168 <+432>:   ldr r3, [r4, #36]   ; 0x24
   0xb6d2c16c <+436>:   ldr r1, [r4, #8]
   0xb6d2c170 <+440>:   ldr r2, [r4, #12]
   0xb6d2c174 <+444>:   sub r3, r3, #2
   0xb6d2c178 <+448>:   and r2, r2, r1
   0xb6d2c17c <+452>:   cmp r3, #1
   0xb6d2c180 <+456>:   cmnls   r2, #1
   0xb6d2c184 <+460>:   str r3, [r4, #36]   ; 0x24
   0xb6d2c188 <+464>:   beq 0xb6d2c290 <pthread_cond_wait@@GLIBC_2.4+728>
   0xb6d2c18c <+468>:   mov r3, #0
   0xb6d2c190 <+472>:   mcr 15, 0, r0, cr7, cr10, {5}
   0xb6d2c194 <+476>:   ldrex   r2, [r4]
   0xb6d2c198 <+480>:   strex   r1, r3, [r4]
   0xb6d2c19c <+484>:   cmp r1, #0
   0xb6d2c1a0 <+488>:   bne 0xb6d2c194 <pthread_cond_wait@@GLIBC_2.4+476>
   0xb6d2c1a4 <+492>:   cmp r2, #1
   0xb6d2c1a8 <+496>:   bgt 0xb6d2c278 <pthread_cond_wait@@GLIBC_2.4+704>
   0xb6d2c1ac <+500>:   ldr r0, [sp, #20]
   0xb6d2c1b0 <+504>:   mov r1, #0
---Type <return> to continue, or q <return> to quit---
   0xb6d2c1b4 <+508>:   bl  0xb6d2e9d0 <_pthread_cleanup_pop>
   0xb6d2c1b8 <+512>:   ldr r0, [sp, #12]
   0xb6d2c1bc <+516>:   bl  0xb6d2a990 <__pthread_mutex_cond_lock>
   0xb6d2c1c0 <+520>:   add sp, sp, #68 ; 0x44
   0xb6d2c1c4 <+524>:   pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
   0xb6d2c1c8 <+528>:   mov r6, r3
   0xb6d2c1cc <+532>:   str r2, [sp, #48]   ; 0x30
   0xb6d2c1d0 <+536>:   mov r0, r4
   0xb6d2c1d4 <+540>:   mov r1, r6
   0xb6d2c1d8 <+544>:   bl  0xb6d2ef88 <__lll_lock_wait>
   0xb6d2c1dc <+548>:   b   0xb6d2c004 <pthread_cond_wait@@GLIBC_2.4+76>
   0xb6d2c1e0 <+552>:   mov r0, r4
   0xb6d2c1e4 <+556>:   ldr r1, [sp, #16]
   0xb6d2c1e8 <+560>:   mov r2, #1
   0xb6d2c1ec <+564>:   mov r3, #0
   0xb6d2c1f0 <+568>:   mov r7, #240    ; 0xf0
   0xb6d2c1f4 <+572>:   svc 0x00000000
   0xb6d2c1f8 <+576>:   b   0xb6d2c0c8 <pthread_cond_wait@@GLIBC_2.4+272>
   0xb6d2c1fc <+580>:   mov r3, #0
   0xb6d2c200 <+584>:   str r3, [sp, #48]   ; 0x30
   0xb6d2c204 <+588>:   mov r3, #1
   0xb6d2c208 <+592>:   ldrex   r2, [r4]
   0xb6d2c20c <+596>:   cmp r2, #0
   0xb6d2c210 <+600>:   bne 0xb6d2c224 <pthread_cond_wait@@GLIBC_2.4+620>
   0xb6d2c214 <+604>:   strex   r1, r3, [r4]
   0xb6d2c218 <+608>:   cmp r1, #0
   0xb6d2c21c <+612>:   bne 0xb6d2c208 <pthread_cond_wait@@GLIBC_2.4+592>
   0xb6d2c220 <+616>:   mcr 15, 0, r0, cr7, cr10, {5}
   0xb6d2c224 <+620>:   strne   r2, [sp, #48]   ; 0x30
   0xb6d2c228 <+624>:   movne   r6, #128    ; 0x80
   0xb6d2c22c <+628>:   bne 0xb6d2c1d0 <pthread_cond_wait@@GLIBC_2.4+536>
   0xb6d2c230 <+632>:   mov r6, #128    ; 0x80
---Type <return> to continue, or q <return> to quit---
   0xb6d2c234 <+636>:   b   0xb6d2c004 <pthread_cond_wait@@GLIBC_2.4+76>
   0xb6d2c238 <+640>:   mov r3, #0
   0xb6d2c23c <+644>:   mcr 15, 0, r0, cr7, cr10, {5}
   0xb6d2c240 <+648>:   ldrex   r2, [r4]
   0xb6d2c244 <+652>:   strex   r1, r3, [r4]
   0xb6d2c248 <+656>:   cmp r1, #0
   0xb6d2c24c <+660>:   bne 0xb6d2c240 <pthread_cond_wait@@GLIBC_2.4+648>
   0xb6d2c250 <+664>:   cmp r2, #1
   0xb6d2c254 <+668>:   movle   r0, r12
   0xb6d2c258 <+672>:   ble 0xb6d2c1c0 <pthread_cond_wait@@GLIBC_2.4+520>
   0xb6d2c25c <+676>:   mov r0, r4
   0xb6d2c260 <+680>:   eor r1, r6, #129    ; 0x81
   0xb6d2c264 <+684>:   mov r2, #1
   0xb6d2c268 <+688>:   mov r7, #240    ; 0xf0
   0xb6d2c26c <+692>:   svc 0x00000000
   0xb6d2c270 <+696>:   mov r0, r12
   0xb6d2c274 <+700>:   b   0xb6d2c1c0 <pthread_cond_wait@@GLIBC_2.4+520>
   0xb6d2c278 <+704>:   mov r0, r4
   0xb6d2c27c <+708>:   eor r1, r6, #129    ; 0x81
   0xb6d2c280 <+712>:   mov r2, #1
   0xb6d2c284 <+716>:   mov r7, #240    ; 0xf0
   0xb6d2c288 <+720>:   svc 0x00000000
   0xb6d2c28c <+724>:   b   0xb6d2c1ac <pthread_cond_wait@@GLIBC_2.4+500>
   0xb6d2c290 <+728>:   add r0, r4, #36 ; 0x24
   0xb6d2c294 <+732>:   eor r1, r6, #129    ; 0x81
   0xb6d2c298 <+736>:   mov r2, #1
   0xb6d2c29c <+740>:   mov r3, #0
   0xb6d2c2a0 <+744>:   mov r7, #240    ; 0xf0
   0xb6d2c2a4 <+748>:   svc 0x00000000
   0xb6d2c2a8 <+752>:   b   0xb6d2c18c <pthread_cond_wait@@GLIBC_2.4+468>
   0xb6d2c2ac <+756>:           ; <UNDEFINED> instruction: 0xfffffd7c
End of assembler dump.

Let me know if you need the dump and/or binary.

bnoordhuis commented 9 years ago

@silverwind The second thread looks healthy, it's sleeping in a system call. What does disassemble $pc,+32 print for the first thread?

silverwind commented 9 years ago
(gdb) disassemble $pc,+32
Dump of assembler code from 0x5b7242c0 to 0x5b7242e0:
=> 0x5b7242c0:  movw    r10, #63532 ; 0xf82c
   0x5b7242c4:  movt    r10, #473   ; 0x1d9
   0x5b7242c8:  push    {r1}        ; (str r1, [sp, #-4]!)
   0x5b7242cc:  push    {r2}        ; (str r2, [sp, #-4]!)
   0x5b7242d0:  add r2, r4, r3, lsl #2
   0x5b7242d4:  b   0x5b7242e4
   0x5b7242d8:  ldr r0, [r4], #4
   0x5b7242dc:  ldr r0, [r0]
End of assembler dump.
bnoordhuis commented 9 years ago

Thanks. I think V8's feature detection is failing here. Does iojs --noenable_armv7 work?

silverwind commented 9 years ago

Does iojs --noenable_armv7 work

Unfortunately not. It gives a very similar crash:

(gdb) disassemble $pc,+32
Dump of assembler code from 0x351242c0 to 0x351242e0:
=> 0x351242c0:  movw    r10, #26684 ; 0x683c
   0x351242c4:  movt    r10, #455   ; 0x1c7
   0x351242c8:  push    {r1}        ; (str r1, [sp, #-4]!)
   0x351242cc:  push    {r2}        ; (str r2, [sp, #-4]!)
   0x351242d0:  add r2, r4, r3, lsl #2
   0x351242d4:  b   0x351242e4
   0x351242d8:  ldr r0, [r4], #4
   0x351242dc:  ldr r0, [r0]
End of assembler dump.

Right now, I'm trying to compile with some flags, but it'll be another 1-2 hours before it completes:

make arm_version=6 armfpu=vfp armfloatabi=hard armv7=false

bnoordhuis commented 9 years ago

If you still have the binary around, can you try iojs --noenable_movw_movt (possibly combined with --noenable_armv7)?

silverwind commented 9 years ago

Still very much the same, with the first or both flags:

(gdb) core core.iojs.1000.b18201d96bbe48ea9ccce34bd4e17dc7.23537.1421526387000000
[New LWP 23537]
[New LWP 23538]
[New LWP 23541]
[New LWP 23540]
[New LWP 23539]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Core was generated by `iojs --noenable_movw_movt --noenable_armv7'.
Program terminated with signal SIGILL, Illegal instruction.
#0  0x208242c0 in ?? ()
(gdb) info threads
  Id   Target Id         Frame
  5    Thread 0xb6401450 (LWP 23539) 0xb6d4e0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  4    Thread 0xb5c01450 (LWP 23540) 0xb6d4e0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  3    Thread 0xb5401450 (LWP 23541) 0xb6d4e0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  2    Thread 0xb6c01450 (LWP 23538) 0xb6d4e0e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
* 1    Thread 0xb6f5f000 (LWP 23537) 0x208242c0 in ?? ()
(gdb) disassemble $pc,+32
Dump of assembler code from 0x208242c0 to 0x208242e0:
=> 0x208242c0:  movw    r10, #38996 ; 0x9854
   0x208242c4:  movt    r10, #550   ; 0x226
   0x208242c8:  push    {r1}        ; (str r1, [sp, #-4]!)
   0x208242cc:  push    {r2}        ; (str r2, [sp, #-4]!)
   0x208242d0:  add r2, r4, r3, lsl #2
   0x208242d4:  b   0x208242e4
   0x208242d8:  ldr r0, [r4], #4
   0x208242dc:  ldr r0, [r0]
End of assembler dump.
bnoordhuis commented 9 years ago

Hrm, okay. Maybe it's worth building with ./configure --without-snapshot. Flags won't have effect when the movw/movt is baked into the snapshot.

silverwind commented 9 years ago

It's already been build with ./configure --without-snapshot, as doing otherwise results in this:

make -C out BUILDTYPE=Release V=1
make[1]: Entering directory '/home/silverwind/git/io.js/out'
  LD_LIBRARY_PATH=/home/silverwind/git/io.js/out/Release/lib.host:/home/silverwind/git/io.js/out/Release/lib.target:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH; cd ../deps/v8/tools/gyp; mkdir -p /home/silverwind/git/io.js/out/Release/obj.target/v8_snapshot/geni; "/home/silverwind/git/io.js/out/Release/mksnapshot" --log-snapshot-positions --logfile "/home/silverwind/git/io.js/out/Release/obj.target/v8_snapshot/geni/snapshot.log" "/home/silverwind/git/io.js/out/Release/obj.target/v8_snapshot/geni/snapshot.cc"
/bin/sh: line 1: 16261 Illegal instruction     (core dumped) "/home/silverwind/git/io.js/out/Release/mksnapshot" --log-snapshot-positions --logfile "/home/silverwind/git/io.js/out/Release/obj.target/v8_snapshot/geni/snapshot.log" "/home/silverwind/git/io.js/out/Release/obj.target/v8_snapshot/geni/snapshot.cc"
deps/v8/tools/gyp/v8_snapshot.target.mk:13: recipe for target '/home/silverwind/git/io.js/out/Release/obj.target/v8_snapshot/geni/snapshot.cc' failed
make[1]: *** [/home/silverwind/git/io.js/out/Release/obj.target/v8_snapshot/geni/snapshot.cc] Error 132
make[1]: Leaving directory '/home/silverwind/git/io.js/out'
Makefile:52: recipe for target 'iojs' failed
make: *** [iojs] Error 2

Let's await the current build, at least one guy on this thread reports success with these make options.

Cydox commented 9 years ago

@silverwind I already tried those options youre building with right now. I didn´t have succes with them.

@bnoordhuis I´m found out in some other thread that it could help to build with -march=armv6 -mfpu=vfp -mfloat-abi=hard as gcc and g++ compiler options. But I´m not home this week so I can only acces Github and my Pi through my phone. So I´m struggling on finding out how to use those options. I already tried to do make CFLAGS='<the options>' CXXFLAGS='<the options>'. But i think it stopped using those options when it came to compile v8.

How can I use those options? It´s hard to figure out how the makefiles work on a screen of a phone.

bnoordhuis commented 9 years ago

@Cydox It's probably easiest to hack them into the 'cflags' list in common.gypi, the one that now says ['-O3','-ffunction-sections', '-fdata-sections']. I'm not sure if that is going to be enough, though; you also need to stop V8 from generating incompatible machine code.

Cydox commented 9 years ago

Isn´t the architecture detection done in cpu.cc? If thats the case then I think that this might not be the problem because when I used the code:

if (architecture_ == 7) {
       std::cout << "7" << std::endl;
       char* processor;
       processor = cpu_info.ExtractField("Processor");
       if (HasListItem(processor, "(v6l)")) {
         architecture_ = 6;
       }
       processor = cpu_info.ExtractField("model name");
      if (HasListItem(processor, "(v6l)")) {
        std::cout << "6" << std::endl;
        architecture_ = 6;
      }
      delete[] processor;
    }
  }

It printed '6' so it should have detected armv6 right? Or am I horrible wrong with this point?

bnoordhuis commented 9 years ago

@Cydox I'm not 100% sure but I believe some ARMv6 cores support the movw/movt instructions. V8 may think yours is one when it's not (assuming it's crashing for the same reason as @silverwind.)

Cydox commented 9 years ago

@silverwind what does iojs --v8-options print?

silverwind commented 9 years ago

Well mine is a RPi B model, and another user in IRC had the crash on a B+. Comparing to above cpuinfo, mine does show a revision 000d instead of 000b.

Here's the options: https://gist.github.com/silverwind/1a06574749820ae8bd83

Cydox commented 9 years ago

OK think v8 is detecting your rPi as armv7 armv7=1 .

I started a build just now with the options and changes mentioned on this website http://razberry.z-wave.me/index.php?id=28

Cydox commented 9 years ago

But i think I´ll have the result tomorrow(I´m in Germany UTC +1).

silverwind commented 9 years ago

@Cydox your were right, my second build gave me another crashing binary, so those flags don't seem to reach the v8 make call, hopefully yours do.

Cydox commented 9 years ago

My options didn´t work. @silverwind as you said I think the options might not get to the v8 makefile. @bnoordhuis Could this be the problem?

silverwind commented 9 years ago

Started off another build with this in common.gypi:

'cflags': [ '-O3', '-ffunction-sections', '-fdata-sections', '-march=armv6', '-mfpu=vfp', '-mfloat-abi=hard' ]

These definately reach the compiler, here's a call:

  cc '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D_GNU_SOURCE' '-DHAVE_CONFIG_H' '-DCARES_STATICLIB' -I../deps/cares/include -I../deps/cares/src -I../deps/cares/config/linux  -pthread -Wall -Wextra -Wno-unused-parameter -g -pedantic -Wall -Wextra -Wno-unused-parameter --std=gnu89 -O3 -ffunction-sections -fdata-sections -march=armv6 -mfpu=vfp -mfloat-abi=hard -fno-omit-frame-pointer  -MMD -MF /home/silverwind/git/io.js/out/Release/.deps//home/silverwind/git/io.js/out/Release/obj.target/cares/deps/cares/src/ares__close_sockets.o.d.raw  -c -o /home/silverwind/git/io.js/out/Release/obj.target/cares/deps/cares/src/ares__close_sockets.o ../deps/cares/src/ares__close_sockets.c
bnoordhuis commented 9 years ago

@Cydox io.js doesn't use the Makefile in deps/v8, that's for standalone builds. That's why I suggested patching common.gypi in the top-level directory, settings there affect all sub-components.

You'd have to check the Makefile to find out what gyp settings correspond to the Makefile flags that @silverwind mentioned (arm_version=6 armfpu=vfp armfloatabi=hard armv7=false.)

For example, you can set armfloatabi=hard with export GYP_DEFINES="arm_float_abi=hard"; ./configure && make or you add it to the variables section in common.gypi.

By the way, if you want to speed up the build, pass --without-ssl to configure, that skips the OpenSSL build.

silverwind commented 9 years ago

By the way, if you want to speed up the build, pass --without-ssl to configure, that skips the OpenSSL build.

I require OpenSSL for my projects, so I'll leave it in. Will report back in around 4 hours :)

silverwind commented 9 years ago

Build finished, still did armv7 :sob:

$ ./iojs --v8-options | head -2
target arm v6 vfp3 hard
ARMv7=1 VFP3=1 VFP32DREGS=1 NEON=0 SUDIV=0 UNALIGNED_ACCESSES=1 MOVW_MOVT_IMMEDIATE_LOADS=0 COHERENT_CACHE=0 USE_EABI_HARDFLOAT=1
silverwind commented 9 years ago

Went ahead and hardcoded architecture_ = 6 in deps/v8/src/base/cpu.cc in addition to the CFLAGS above, let's see how that goes.

silverwind commented 9 years ago

Build finished. Same result as before, ARMv7=1. Maybe the issue is with passing options down to v8? For example, if I set --enable_neon, shouldn't it print NEON=1 here:

$ ./iojs --noenable_armv7 --enable_neon --v8-options | head -2
target arm v6 vfp3 hard
ARMv7=1 VFP3=1 VFP32DREGS=1 NEON=0 SUDIV=0 UNALIGNED_ACCESSES=1 MOVW_MOVT_IMMEDIATE_LOADS=0 COHERENT_CACHE=0 USE_EABI_HARDFLOAT=1

Also from what I understand, ARMv7 instructions are chosen at runtime, not compile time, or else there couldn't be an option for them.

bnoordhuis commented 9 years ago

I believe NEON is implied by ARMv7. If you pass --noenable_armv7, it will always be disabled.

Is it still SIGILL'ing at a movw/movt instruction sequence?

silverwind commented 9 years ago

Yes, still movw/movt:

GNU gdb (GDB) 7.8.2
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "armv6l-unknown-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/silverwind/git/io.js/iojs...done.
(gdb) core core.iojs.1000.b18201d96bbe48ea9ccce34bd4e17dc7.7805.1421642201000000
[New LWP 7805]
[New LWP 7806]
[New LWP 7808]
[New LWP 7809]
[New LWP 7807]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Core was generated by `./iojs --noenable_armv7'.
Program terminated with signal SIGILL, Illegal instruction.
#0  0x39f242c0 in ?? ()
(gdb) disassemble
No function contains program counter for selected frame.
(gdb) info threads
  Id   Target Id         Frame
  5    Thread 0xb6427450 (LWP 7807) 0xb6d740e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  4    Thread 0xb5427450 (LWP 7809) 0xb6d740e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  3    Thread 0xb5c27450 (LWP 7808) 0xb6d740e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
  2    Thread 0xb6c27450 (LWP 7806) 0xb6d740e4 in pthread_cond_wait@@GLIBC_2.4 () from /usr/lib/libpthread.so.0
* 1    Thread 0xb6f85000 (LWP 7805) 0x39f242c0 in ?? ()
(gdb) disassemble $pc,+32
Dump of assembler code from 0x39f242c0 to 0x39f242e0:
=> 0x39f242c0:  movw    r10, #22588 ; 0x583c
   0x39f242c4:  movt    r10, #584   ; 0x248
   0x39f242c8:  push    {r1}        ; (str r1, [sp, #-4]!)
   0x39f242cc:  push    {r2}        ; (str r2, [sp, #-4]!)
   0x39f242d0:  add r2, r4, r3, lsl #2
   0x39f242d4:  b   0x39f242e4
   0x39f242d8:  ldr r0, [r4], #4
   0x39f242dc:  ldr r0, [r0]
End of assembler dump.
(gdb)

I almost believe that v8 performs architecture detection during runtime, which would explain why all the compiler switches don't seem to have any effect.

Do you remember where in the code the first two lines on iojs --v8-options are printed? They don't appear in a node 0.10 binary, and maybe it's possible to backtrace the problem from there.

silverwind commented 9 years ago

Also relevant:

Linux pi 3.12.36-1-ARCH #1 PREEMPT Thu Jan 15 21:54:44 MST 2015 armv6l GNU/Linux

Kernel 3.9.3 introduced the different cpuinfo if I recall correctly. I'm not sure if I can safely downgrade my kernel, but I'd like to see someone with kernel < 3.9 try a build (with mentioned configure switch).

bnoordhuis commented 9 years ago

@silverwind Does this patch help?

diff --git a/deps/v8/src/base/cpu.cc b/deps/v8/src/base/cpu.cc
index 56e1c46..9bd1b97 100644
--- a/deps/v8/src/base/cpu.cc
+++ b/deps/v8/src/base/cpu.cc
@@ -450,6 +450,14 @@ CPU::CPU()
       }
       delete[] processor;
     }
+
+    if (architecture_ == 7) {
+      char* processor = cpu_info.ExtractField("model name");
+      if (HasListItem(processor, "(v6l)")) {
+        architecture_ = 6;
+      }
+      delete[] processor;
+    }
   }

   // Try to extract the list of CPU features from ELF hwcaps.
silverwind commented 9 years ago

Will try after my current build (with some hackery in v8's makefile) finishes, but I'm not sure it will help, as hardcoding architecture_ = 6 didn't help before.

silverwind commented 9 years ago

@bnoordhuis patch didn't help, same crash signature. If it helps, node 0.11 HEAD crashes with the exact same signature too.

silverwind commented 9 years ago

@bnoordhuis @indutny any more suggestions on what to try? I'm pretty much out of ideas besides randomly hacking up the v8 source. Could you point me to the v8 call that gives variables like ARMv7=1? Maybe I can backtrace from there.

bnoordhuis commented 9 years ago

@silverwind It's from CpuFeatures::PrintFeatures() in deps/v8/src/arm/assembler-arm.cc. But beware, it's a rather deep rabbit hole that you are about to enter. :-)

wilson0x4d commented 9 years ago

Reposted from another thread:

I also had previously edited configure to force the use of "vfpv2" instead of "vfpv3" by changing:

o['variables']['arm_fpu'] = 'vfpv3' # V8 3.18 no longer supports VFP2. to o['variables']['arm_fpu'] = 'vfpv2' # V8 3.18 no longer supports VFP2.

In addition to the armv6 change to cpu.cc.

Since "vfpv2" isn't considered supported in "v8" I have not generated a patch (I'm really not sure what the correct action is wrt the configure script tbh.) My limited understanding is that 'vfp' are floating point extensions, and my assumption here is that by specifying vfpv2 the node build is omitting said extensions (as the VFP3=0 from --v8-options suggests.) Thus, someone will probably want to generate an appropriate patch to configure, or perhaps give me some insight into what scenarios it is acceptable (or unacceptable) to opt out of VFPv3.