Skip to content
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

cmd/compile: missing error reports for program with large stack frame #63616

Open
cuonglm opened this issue Oct 18, 2023 · 4 comments
Open

cmd/compile: missing error reports for program with large stack frame #63616

cuonglm opened this issue Oct 18, 2023 · 4 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@cuonglm
Copy link
Member

cuonglm commented Oct 18, 2023

What version of Go are you using (go version)?

tip

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

What did you do?

Compile following program:

package main

func g() {
	xs := [32537630 / 8][33]int{}
	for _, x := range xs {
		if len(x) > 50 {

		}
	}
}

func main() {
	g()
}

What did you expect to see?

Error reported, like go1.19 and before:

$ go1.19.13 tool compile main.go
main.go:3:6: stack frame too large (>1GB): 1024 MB locals + 0 MB args
main.go:12:6: stack frame too large (>1GB): 1024 MB locals + 0 MB args

What did you see instead?

Runtime error:

go run -trimpath main.go                
runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc00004a740 stack=[0xc00004a000, 0xc00004a800]
fatal error: stack overflow

runtime stack:
runtime.throw({0x467f1a?, 0x8?})
	runtime/panic.go:1018 +0x5c fp=0x7ffcf1cea568 sp=0x7ffcf1cea538 pc=0x42cddc
runtime.newstack()
	runtime/stack.go:1103 +0x5ac fp=0x7ffcf1cea718 sp=0x7ffcf1cea568 pc=0x44476c
runtime.morestack()
	runtime/asm_amd64.s:593 +0x8f fp=0x7ffcf1cea720 sp=0x7ffcf1cea718 pc=0x454b8f

goroutine 1 [running]:
main.main()
	./main.go:12 +0x65 fp=0xc00004a750 sp=0xc00004a748 pc=0x457ca5
runtime.main()
	runtime/proc.go:269 +0x29d fp=0xc00004a7e0 sp=0xc00004a750 pc=0x42f8dd
runtime.goexit({})
	runtime/asm_amd64.s:1671 +0x1 fp=0xc00004a7e8 sp=0xc00004a7e0 pc=0x454e61

goroutine 2 [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
	runtime/proc.go:400 +0xce fp=0xc00004afa8 sp=0xc00004af88 pc=0x42fd0e
runtime.goparkunlock(...)
	runtime/proc.go:406
runtime.forcegchelper()
	runtime/proc.go:324 +0xb3 fp=0xc00004afe0 sp=0xc00004afa8 pc=0x42fb93
runtime.goexit({})
	runtime/asm_amd64.s:1671 +0x1 fp=0xc00004afe8 sp=0xc00004afe0 pc=0x454e61
created by runtime.init.6 in goroutine 1
	runtime/proc.go:312 +0x1a

goroutine 3 [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
	runtime/proc.go:400 +0xce fp=0xc00004b780 sp=0xc00004b760 pc=0x42fd0e
runtime.goparkunlock(...)
	runtime/proc.go:406
runtime.bgsweep(0xc00006c000)
	runtime/mgcsweep.go:276 +0x94 fp=0xc00004b7c8 sp=0xc00004b780 pc=0x41d674
runtime.gcenable.gowrap1()
	runtime/mgc.go:203 +0x25 fp=0xc00004b7e0 sp=0xc00004b7c8 pc=0x412965
runtime.goexit({})
	runtime/asm_amd64.s:1671 +0x1 fp=0xc00004b7e8 sp=0xc00004b7e0 pc=0x454e61
created by runtime.gcenable in goroutine 1
	runtime/mgc.go:203 +0x66

goroutine 4 [GC scavenge wait]:
runtime.gopark(0xc00006c000?, 0x47e678?, 0x1?, 0x0?, 0xc000006d00?)
	runtime/proc.go:400 +0xce fp=0xc00004bf78 sp=0xc00004bf58 pc=0x42fd0e
runtime.goparkunlock(...)
	runtime/proc.go:406
runtime.(*scavengerState).park(0x4cad00)
	runtime/mgcscavenge.go:425 +0x49 fp=0xc00004bfa8 sp=0xc00004bf78 pc=0x41b069
runtime.bgscavenge(0xc00006c000)
	runtime/mgcscavenge.go:653 +0x3c fp=0xc00004bfc8 sp=0xc00004bfa8 pc=0x41b5fc
runtime.gcenable.gowrap2()
	runtime/mgc.go:204 +0x25 fp=0xc00004bfe0 sp=0xc00004bfc8 pc=0x412905
runtime.goexit({})
	runtime/asm_amd64.s:1671 +0x1 fp=0xc00004bfe8 sp=0xc00004bfe0 pc=0x454e61
created by runtime.gcenable in goroutine 1
	runtime/mgc.go:204 +0xa5
exit status 2
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Oct 18, 2023
@cuonglm cuonglm added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Oct 18, 2023
@zigo101
Copy link

zigo101 commented Oct 19, 2023

The behavior changed since 1.20. But the numbers used by gc and the runtime have been inconsistent for a long time.
For example, the following program will always crash at run time:

package main

func g() {
	xs := [1<<29]byte{} // 512M
	for _, x := range xs {
		if x > 50 {

		}
	}
}

var a any

func main() {
	g()
}

It looks the compiler uses 1<<30, but the runtime uses 100000000. That means the actually max stack size is 1<<29 (So maybe gc should also use the number).

@cuonglm
Copy link
Member Author

cuonglm commented Oct 19, 2023

@go101 Yes, but the main purpose of this issue is understanding whether compiler change is expected.

I think the answer should be no, because the program crashing at runtime by the way.

I do not have a chance to bisecting yet.

@zigo101
Copy link

zigo101 commented Oct 19, 2023

If the consistency was also there, then I think it is not important whether or not to restore to the old behavior.

But it is always good to find the cause of the change.

@zigo101
Copy link

zigo101 commented Oct 19, 2023

Ah, it looks this is not only an inconsistency problem between gc and runtime, but also between different gc versions.

gc 1.19 and 1.20 agree on g, but not on f. (So it is not simply a number setting problem.)

//go:noinline
func f() {
	xs := [32537629][33]byte{}
	for _, x := range xs {
		if len(x) > 50 {

		}
	}
}

//go:noinline
func g() {
	xs := [0x3fffffe9]byte{}
	for _, x := range xs {
		if x > 50 {

		}
	}
}
$ gotv 1.19. run main.go
[Run]: $HOME/.cache/gotv/tag_go1.19.13/bin/go run main.go
# command-line-arguments
./main.go:6:6: stack frame too large (>1GB): 1023 MB locals + 0 MB args + 0 MB callee
./main.go:16:6: stack frame too large (>1GB): 1023 MB locals + 0 MB args + 0 MB callee

$ gotv 1.20. run main.go
[Run]: $HOME/.cache/gotv/tag_go1.20.10/bin/go run main.go
# command-line-arguments
./main.go:16:6: stack frame too large (>1GB): 1023 MB locals + 0 MB args + 0 MB callee

[edit] Changing the loop vars as global vars will remove the inconsistency between gc versions. So it might be related to a change of the for-range implementation.

@mknyszek mknyszek added this to the Backlog milestone Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
Development

No branches or pull requests

5 participants