• nodejs 8 terminate called after throwing an instance of 'std::lengt

    From James Cowgill@21:1/5 to =?UTF-8?B?SsOpcsOpbXkgTGFs?= on Wed Jan 17 11:30:01 2018
    To: debian-mips@lists.debian.org

    This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --oDfrT64nBeNjOnz1nZwDwdt7Be52qxB6g
    Content-Type: text/plain; charset=utf-8
    Content-Language: en-US
    Content-Transfer-Encoding: quoted-printable

    Hi,

    On 06/01/18 15:20, Jérémy Lal wrote:
    This error happens on mipsel only: https://buildd.debian.org/status/fetch.php?pkg=nodejs&arch=mipsel&ver=8.9.3~dfsg-6&stamp=1515132264&raw=0

    Maybe it's related to a bug in another package, is it a known issue ?

    I believe you have hit one of the infamous Loongson FPU "bugs" [1].

    This is an extract from the disassembly of nodejs in v8::internal::compiler::Scheduler::ComputeSchedule:
    lwc1 $f1,-392(v0)
    mul.s $f0,$f0,$f2
    c.le.s $f1,$f0
    bc1t 0x55cd6990

    The C code for this is:
    float node_hint_multiplier = (flags & Scheduler::kSplitNodes) ? 1.1 : 1;
    size_t node_count_hint = node_hint_multiplier * graph->NodeCount();

    After the lwc (which loads INT_MAX as a float) we have this in the float registers according to gdb:
    f0: 0x44094000 flt: 549 dbl: 3.5336950251869015e+72
    f1: 0x4f000000 flt: 2.14748365e+09
    f2: 0x3f800000 flt: 1 dbl: 1073742078
    f3: 0x41d00000 flt: 26

    But after the multiplication we lose the value in f1:
    f0: 0x44094000 flt: 549 dbl: 5.6395463852218459e-315
    f1: 0x00000000 flt: 0
    f2: 0x3f800000 flt: 1 dbl: 1073742078
    f3: 0x41d00000 flt: 26

    The result of the comparison (c.le.s) then changes and we branch (bc1t)
    when we should not. The end result is we end up with node_count_hint
    being set to 0x80000000 which later causes the length_error.

    In gcc, the Loongson bugs are worked around on mipsel by:
    - Disabling fused multiply + add instructions completely
    - Enabling FPXX which (as a side effect) disables use of odd FP
    registers for single precision arithmetic.

    In nodejs you allow the use of odd FP registers by compiling with FP32.
    I think if you add "-mno-odd-spreg" to your CFLAGS (and CXXFLAGS) then
    you should be able to avoid these issues in C code (and fix this
    specific bug). Unfortunately avoiding them in JITed code is a lot more
    complex :/

    Yunqiang, should we enable --without-odd-spreg-32 when compiling gcc on
    mipsel? I think that will also fix this.

    James

    ---

    [1] Extract from Loongson 3A processor manual (google translated from
    chinese so forgive the english):

    The GS464 is compatible with the MIPS64 Release 2 release and
    functionally implements all the FPU instructions specified by the MIPS64 architecture,
    However, there are some instructions in the implementation of subtle compatibility does not affect but more important difference, the
    following two points worth the attention of programmers.
    (1) multiply plus, multiply minus instruction. When executing the four instruction sets of MADD.fmt, MSUB.fmt, NMADD.fmt and NMSUB.fmt, the
    operation result of GS464 is slightly different from that of MIPS64
    processor because GS464 only performs multiply-add operation only at the
    final result
    Do precision rounding, and the MIPS64 processor carried out after the
    operation of a rounding, adding an additional round, resulting in
    The final result of a minimum difference of 1.
    (2) Single-precision arithmetic instructions. When the FR bit in the
    Status co