wasilibs / go-re2

Drop-in replacement for regexp using re2, for any Go app
MIT License
140 stars 16 forks source link

"Illegal instruction" on an ARMv8.1 instruction set CPU. #136

Open bingfengfeifei opened 3 months ago

bingfengfeifei commented 3 months ago

In version 1.4.0, the demo code runs successfully, but starting from version 1.5.0, the demo code panics with an instruction set error. demo code:

package main

import (
        "fmt"

        "github.com/wasilibs/go-re2"
)

func main() {
        reg := re2.MustCompile(`\d+`)
        fmt.Println(reg.MatchString("123"))
}

error log:

SIGILL: illegal instruction
PC=0xffff610b01f4 m=0 sigcode=1
instruction bytes: 0xa 0xfd 0xeb 0x88 0xe8 0x3 0xb 0x2a 0xea 0x3 0x1f 0x32 0x1f 0x1 0xa 0x6b

goroutine 1 [running, locked to thread]:
runtime: g 1: unknown pc 0xffff610b01f4
stack: frame={sp:0x4101231fa0, fp:0x0} stack=[0x41014a0000,0x41014b0000)

runtime: g 1: unknown pc 0xffff610b01f4
stack: frame={sp:0x4101231fa0, fp:0x0} stack=[0x41014a0000,0x41014b0000)

goroutine 2 [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000042f90 sp=0x4000042f70 pc=0x47ee8
runtime.goparkunlock(...)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:404
runtime.forcegchelper()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:322 +0xb8 fp=0x4000042fd0 sp=0x4000042f90 pc=0x47d78
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x4000042fd0 sp=0x4000042fd0 pc=0x76694
created by runtime.init.6 in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:310 +0x24

goroutine 3 [GC sweep wait]:
runtime.gopark(0x1?, 0x0?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000043760 sp=0x4000043740 pc=0x47ee8
runtime.goparkunlock(...)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:404
runtime.bgsweep(0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgcsweep.go:321 +0x108 fp=0x40000437b0 sp=0x4000043760 pc=0x34058
runtime.gcenable.func1()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:200 +0x28 fp=0x40000437d0 sp=0x40000437b0 pc=0x28b08
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x40000437d0 sp=0x40000437d0 pc=0x76694
created by runtime.gcenable in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:200 +0x6c

goroutine 4 [GC scavenge wait]:
runtime.gopark(0x4000062000?, 0x28d0e8?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000043f50 sp=0x4000043f30 pc=0x47ee8
runtime.goparkunlock(...)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:404
runtime.(*scavengerState).park(0x481a60)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgcscavenge.go:425 +0x5c fp=0x4000043f80 sp=0x4000043f50 pc=0x318bc
runtime.bgscavenge(0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgcscavenge.go:658 +0xac fp=0x4000043fb0 sp=0x4000043f80 pc=0x31e6c
runtime.gcenable.func2()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:201 +0x28 fp=0x4000043fd0 sp=0x4000043fb0 pc=0x28aa8
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x4000043fd0 sp=0x4000043fd0 pc=0x76694
created by runtime.gcenable in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:201 +0xac

goroutine 5 [finalizer wait]:
runtime.gopark(0x40000425a8?, 0x72554?, 0x1?, 0x25?, 0x88154?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000042580 sp=0x4000042560 pc=0x47ee8
runtime.runfinq()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mfinal.go:193 +0x108 fp=0x40000427d0 sp=0x4000042580 pc=0x27bb8
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x40000427d0 sp=0x40000427d0 pc=0x76694
created by runtime.createfing in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mfinal.go:163 +0x80

goroutine 6 [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000044730 sp=0x4000044710 pc=0x47ee8
runtime.gcBgMarkWorker()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1295 +0xd8 fp=0x40000447d0 sp=0x4000044730 pc=0x2a768
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x40000447d0 sp=0x40000447d0 pc=0x76694
created by runtime.gcBgMarkStartWorkers in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1219 +0x28

goroutine 17 [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x400003e730 sp=0x400003e710 pc=0x47ee8
runtime.gcBgMarkWorker()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1295 +0xd8 fp=0x400003e7d0 sp=0x400003e730 pc=0x2a768
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x400003e7d0 sp=0x400003e7d0 pc=0x76694
created by runtime.gcBgMarkStartWorkers in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1219 +0x28

goroutine 7 [GC worker (idle)]:
runtime.gopark(0xc5bbdd3227e6d?, 0x0?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000044f30 sp=0x4000044f10 pc=0x47ee8
runtime.gcBgMarkWorker()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1295 +0xd8 fp=0x4000044fd0 sp=0x4000044f30 pc=0x2a768
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x4000044fd0 sp=0x4000044fd0 pc=0x76694
created by runtime.gcBgMarkStartWorkers in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1219 +0x28

goroutine 33 [GC worker (idle)]:
runtime.gopark(0xc5bbdd3201ba4?, 0x0?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000092730 sp=0x4000092710 pc=0x47ee8
runtime.gcBgMarkWorker()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1295 +0xd8 fp=0x40000927d0 sp=0x4000092730 pc=0x2a768
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x40000927d0 sp=0x40000927d0 pc=0x76694
created by runtime.gcBgMarkStartWorkers in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1219 +0x28

goroutine 18 [GC worker (idle)]:
runtime.gopark(0xc5bbdd31f14e7?, 0x0?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x400003ef30 sp=0x400003ef10 pc=0x47ee8
runtime.gcBgMarkWorker()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1295 +0xd8 fp=0x400003efd0 sp=0x400003ef30 pc=0x2a768
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x400003efd0 sp=0x400003efd0 pc=0x76694
created by runtime.gcBgMarkStartWorkers in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1219 +0x28

goroutine 8 [GC worker (idle)]:
runtime.gopark(0xc5bbdd32236b4?, 0x0?, 0x0?, 0x0?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000045730 sp=0x4000045710 pc=0x47ee8
runtime.gcBgMarkWorker()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1295 +0xd8 fp=0x40000457d0 sp=0x4000045730 pc=0x2a768
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x40000457d0 sp=0x40000457d0 pc=0x76694
created by runtime.gcBgMarkStartWorkers in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1219 +0x28

goroutine 34 [GC worker (idle)]:
runtime.gopark(0xc5bbdd3224fc8?, 0x1?, 0x90?, 0xb5?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x4000092f30 sp=0x4000092f10 pc=0x47ee8
runtime.gcBgMarkWorker()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1295 +0xd8 fp=0x4000092fd0 sp=0x4000092f30 pc=0x2a768
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x4000092fd0 sp=0x4000092fd0 pc=0x76694
created by runtime.gcBgMarkStartWorkers in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1219 +0x28

goroutine 19 [GC worker (idle)]:
runtime.gopark(0x4b6480?, 0x1?, 0x43?, 0xc2?, 0x0?)
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/proc.go:398 +0xc8 fp=0x400003f730 sp=0x400003f710 pc=0x47ee8
runtime.gcBgMarkWorker()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1295 +0xd8 fp=0x400003f7d0 sp=0x400003f730 pc=0x2a768
runtime.goexit()
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/asm_arm64.s:1197 +0x4 fp=0x400003f7d0 sp=0x400003f7d0 pc=0x76694
created by runtime.gcBgMarkStartWorkers in goroutine 1
        /root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.21.5.linux-amd64/src/runtime/mgc.go:1219 +0x28

r0      0x4000105660
r1      0x41017fec90
r2      0x4000105660
r3      0x41017fec90
r4      0x0
r5      0x4101231ff0
r6      0x4000105600
r7      0x4000105660
r8      0x4000210a90
r9      0x4000200000
r10     0x1
r11     0x0
r12     0x3
r13     0x4
r14     0x4
r15     0x4101e7ddd0
r16     0x41014a03a0
r17     0x41014af330
r18     0x0
r19     0x0
r20     0x4000105660
r21     0x41014af898
r22     0x4000046028
r23     0x28fc78
r24     0xffff610b0110
r25     0x2538e0
r26     0x4101231ff0
r27     0x30
r28     0x40000021a0
r29     0x41014af268
lr      0xffff614f001c
sp      0x4101231fa0
pc      0xffff610b01f4
fault   0x0

lscpu

Architecture: aarch64
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 1
Core(s) per socket: 8
Socket(s): 1
NUMA node(s): 1
Model: 3
CPU max MHz: 2100.0000
CPU min MHz: 2100.0000
BogoMIPS: 100.00
L1d cache: unknown size
L1i cache: unknown size
L2 cache: unknown size
NUMA node0 CPU(s): 0-7
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
anuraaga commented 3 months ago

Hi @bingfengfeifei - what is the actual CPU type by the way? Since 1.5, we use atomic operations, but AFAIK, those are mandatory on Armv8.1

https://en.wikichip.org/wiki/arm/armv8.1

When I do lscpu on my Macbook, I see an atomics flag which yours is missing so I wonder if it is actually Armv8.1. I don't think we can support older than it since we need atomics for memory usage optimization (1.4 will consume much more memory), and it's a very old architecture by now.

Architecture:             aarch64
  CPU op-mode(s):         64-bit
  Byte Order:             Little Endian
CPU(s):                   10
  On-line CPU(s) list:    0-9
Vendor ID:                Apple
  Model name:             -
    Model:                0
    Thread(s) per core:   1
    Core(s) per cluster:  10
    Socket(s):            -
    Cluster(s):           1
    Stepping:             0x0
    BogoMIPS:             48.00
    Flags:                fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm dit uscat ilrc
                          pc flagm ssbs sb paca pacg dcpodp flagm2 frint
bingfengfeifei commented 3 months ago

Hi @anuraaga - Thank you for the reply. This CPU may not be a true ArmV8.1, it may be ArmV8. The CPU model is Phytium D2000.

anuraaga commented 3 months ago

Thanks for confirming. Searching around, indeed it seems to be armv8. While there are techniques for emulating atomics on it, wazero is a small community and I don't know if we could support less common cpus. We could file an issue in wazero repo if you want to try but I think the chance is low.

A workaround for you could be to use the cgo backend with the build tag if you compile re2 (https://github.com/google/re2) for that CPU. Is it something possible?