expr-lang / expr

Expression language and expression evaluation for Go
https://expr-lang.org
MIT License
6.35k stars 408 forks source link

*vm.Program Not Safe #683

Open xuanP opened 4 months ago

xuanP commented 4 months ago

Hi I'm trying to reuse compiled Program but it seems unsafe, while the document here saying it is. I reuse the program in multiple goroutines and encounter PANIC. Here's the stack, i'm using @v1.16.9:

`fatal error: concurrent map read and map write

goroutine 73084 [running]: reflect.mapaccess(0x3f2a520?, 0x65f9ad0?, 0x4?) /usr/local/go/src/runtime/map.go:1357 +0x19 reflect.Value.MapIndex({0x4039fc0?, 0xc005644f00?, 0xc0027bb580?}, {0x3f2a520, 0x65f9ad0, 0x82}) /usr/local/go/src/reflect/value.go:1747 +0x156 github.com/expr-lang/expr/vm/runtime.Fetch({0x4039fc0, 0xc005644f00?}, {0x3f2a520?, 0x65f9ad0?}) /opt/tiger/compile_path/pkg/mod/github.com/expr-lang/expr@v1.16.9/vm/runtime/runtime.go:55 +0x2d6 github.com/expr-lang/expr/vm.(*VM).Run(0xc0027bbad0, 0xc0026c9200, {0x43746c0?, 0xc00dec4c40?}) /opt/tiger/compile_path/pkg/mod/github.com/expr-lang/expr@v1.16.9/vm/vm.go:130 +0xc30 github.com/expr-lang/expr/vm.Run(0x7f086cd0c108?, {0x43746c0?, 0xc00dec4c40?}) /opt/tiger/compile_path/pkg/mod/github.com/expr-lang/expr@v1.16.9/vm/vm.go:25 +0x70 github.com/expr-lang/expr.Run(...) `

antonmedv commented 4 months ago

Hi,

Yes, vm.Program is safe to run in multiple goroutines and is concurrent safe. Expr even has a special race test in CI to verify what it is true: https://github.com/expr-lang/expr/blob/c42572b9c7d8471776ed9a8b5bade850cff73d26/.github/workflows/test.yml#L35

In the provided error, I see runtime.Fetch -> reflect.Value.MapIndex calls. I suspect some sort of map is used in env and both program tries to read those values from different goroutines at the same time other goroutines writes to the map.

Make sure what your code is thread safe as well. Lock access to env while reading from it.