Skip to content

global regexps cause interp to stack overflow #2176

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
dgryski opened this issue Oct 14, 2021 · 3 comments
Closed

global regexps cause interp to stack overflow #2176

dgryski opened this issue Oct 14, 2021 · 3 comments

Comments

@dgryski
Copy link
Member

dgryski commented Oct 14, 2021

The following programs dies with stack overflow during the interp pass's "Update all global variables in the LLVM modules" loop, specifically the toLLVMValue call

package main

import (
	"regexp"
)

var foo = regexp.MustCompile("\r\n|[\n\r]")

func main() {
	println(foo.String())
}

A selection of the output follows:

2021/10/13 17:20:23 type main.foo PointerType(PointerType(%regexp.Regexp: StructType(%runtime._string: StructType(PointerType(IntegerType(8 bits)), IntegerType(32 bits)), PointerType(%regexp/syntax.Prog: StructType(StructType(PointerType(%regexp/syntax.Inst: StructType(IntegerType(8 bits), IntegerType(32 bits), IntegerType(32 bits), StructType(PointerType(IntegerType(32 bits)), IntegerType(32 bits), IntegerType(32 bits)))), IntegerType(32 bits), IntegerType(32 bits)), IntegerType(32 bits), IntegerType(32 bits))), PointerType(%regexp.onePassProg: StructType(StructType(PointerType(%regexp.onePassInst: StructType(%regexp/syntax.Inst: StructType(IntegerType(8 bits), IntegerType(32 bits), IntegerType(32 bits), StructType(PointerType(IntegerType(32 bits)), IntegerType(32 bits), IntegerType(32 bits))), StructType(PointerType(IntegerType(32 bits)), IntegerType(32 bits), IntegerType(32 bits)))), IntegerType(32 bits), IntegerType(32 bits)), IntegerType(32 bits), IntegerType(32 bits))), IntegerType(32 bits), IntegerType(32 bits), StructType(PointerType(%runtime._string: StructType(PointerType(IntegerType(8 bits)), IntegerType(32 bits))), IntegerType(32 bits), IntegerType(32 bits)), %runtime._string: StructType(PointerType(IntegerType(8 bits)), IntegerType(32 bits)), StructType(PointerType(IntegerType(8 bits)), IntegerType(32 bits), IntegerType(32 bits)), IntegerType(32 bits), IntegerType(32 bits), IntegerType(32 bits), IntegerType(32 bits), IntegerType(1 bits), IntegerType(8 bits), IntegerType(32 bits), IntegerType(1 bits))))
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc02ac00348 stack=[0xc02ac00000, 0xc04ac00000]
fatal error: stack overflow

runtime stack:
runtime.throw({0x43a659e, 0x45fe0c0})
	/Users/dgryski/go/src/go.googlesource.com/go/src/runtime/panic.go:1198 +0x71
runtime.newstack()
	/Users/dgryski/go/src/go.googlesource.com/go/src/runtime/stack.go:1088 +0x5ac
runtime.morestack()
	/Users/dgryski/go/src/go.googlesource.com/go/src/runtime/asm_amd64.s:461 +0x8b

goroutine 14 [running]:
runtime.mapaccess2_fast32(0x4353200, 0xc009b211d0, 0x7c6)
	/Users/dgryski/go/src/go.googlesource.com/go/src/runtime/map_fast32.go:52 +0x18a fp=0xc02ac00358 sp=0xc02ac00350 pc=0x4014aea
github.com/tinygo-org/tinygo/interp.(*memoryView).get(0xc009b21170, 0x7c6)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:228 +0x9e fp=0xc02ac00460 sp=0xc02ac00358 pc=0x42c1c3e
github.com/tinygo-org/tinygo/interp.pointerValue.llvmValue(...)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:518
github.com/tinygo-org/tinygo/interp.pointerValue.toLLVMValue({0x0}, {0xc0068f4b00}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:526 +0x5b fp=0xc02ac00620 sp=0xc02ac00460 pc=0x42c383b
github.com/tinygo-org/tinygo/interp.rawValue.rawLLVMValue({{0xc0096d85a0, 0x7c6, 0xc02ac007a0}}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:802 +0x1d9 fp=0xc02ac00710 sp=0xc02ac00620 pc=0x42c4a39
github.com/tinygo-org/tinygo/interp.pointerValue.toLLVMValue({0x0}, {0xc0068f4a80}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:535 +0x1c5 fp=0xc02ac008d0 sp=0xc02ac00710 pc=0x42c39a5
github.com/tinygo-org/tinygo/interp.rawValue.rawLLVMValue({{0xc0096d85a0, 0x7c6, 0xc02ac00a50}}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:802 +0x1d9 fp=0xc02ac009c0 sp=0xc02ac008d0 pc=0x42c4a39
github.com/tinygo-org/tinygo/interp.pointerValue.toLLVMValue({0x0}, {0xc0068f4a00}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:535 +0x1c5 fp=0xc02ac00b80 sp=0xc02ac009c0 pc=0x42c39a5
github.com/tinygo-org/tinygo/interp.rawValue.rawLLVMValue({{0xc0096d85a0, 0x7c6, 0xc02ac00d00}}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:802 +0x1d9 fp=0xc02ac00c70 sp=0xc02ac00b80 pc=0x42c4a39
github.com/tinygo-org/tinygo/interp.pointerValue.toLLVMValue({0x0}, {0xc0068f4980}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:535 +0x1c5 fp=0xc02ac00e30 sp=0xc02ac00c70 pc=0x42c39a5
github.com/tinygo-org/tinygo/interp.rawValue.rawLLVMValue({{0xc0096d85a0, 0x7c6, 0x7f5a2252011c}}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:802 +0x1d9 fp=0xc02ac00f20 sp=0xc02ac00e30 pc=0x42c4a39
github.com/tinygo-org/tinygo/interp.pointerValue.toLLVMValue({0x0}, {0xc0068f4900}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:535 +0x1c5 fp=0xc02ac010e0 sp=0xc02ac00f20 pc=0x42c39a5
github.com/tinygo-org/tinygo/interp.rawValue.rawLLVMValue({{0xc0096d85a0, 0x7c6, 0xc02ac01260}}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:802 +0x1d9 fp=0xc02ac011d0 sp=0xc02ac010e0 pc=0x42c4a39
github.com/tinygo-org/tinygo/interp.pointerValue.toLLVMValue({0x0}, {0xc0068f4880}, 0xc009b21170)
	/Users/dgryski/go/src/github.com/tinygo-org/tinygo/interp/memory.go:535 +0x1c5 fp=0xc02ac01390 sp=0xc02ac011d0 pc=0x42c39a5
...
@dgryski
Copy link
Member Author

dgryski commented Oct 14, 2021

So, the problem seems to be that when trying calling pointerValue.toLLVMValue(), the object is nil, and so

initializer, err := obj.buffer.asRawValue(mem.r).rawLLVMValue(mem)

is called, but rawValue.rawLLVMValue() decides to call

field, err := pointerValue{v.buf[i]}.toLLVMValue(llvm.Type{}, mem)

and we're back where we started.

@dkegel-fastly
Copy link
Contributor

cf. #1830 and #1848

@dgryski
Copy link
Member Author

dgryski commented Oct 14, 2021

Indeed. Fixed by #2001. Closing as duplicate.

@dgryski dgryski closed this as completed Oct 14, 2021
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

No branches or pull requests

2 participants