Revert "runtime: get a better g0 stack bound in needm"

This reverts CL 479915.

Reason for revert: breaks a lot google internal tests.

Change-Id: I13a9422e810af7ba58cbf4a7e6e55f4d8cc0ca51
Reviewed-on: https://go-review.googlesource.com/c/go/+/481055
Reviewed-by: Chressie Himpel <chressie@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Cherry Mui 2023-03-31 18:29:10 +00:00
parent 092d43c329
commit 63ef9059a2
10 changed files with 7 additions and 182 deletions

View File

@ -1247,57 +1247,3 @@ func TestPreemption(t *testing.T) {
t.Error(err)
}
}
// Issue 59294. Test calling Go function from C after using some
// stack space.
func TestDeepStack(t *testing.T) {
t.Parallel()
if !testWork {
defer func() {
os.Remove("testp9" + exeSuffix)
os.Remove("libgo9.a")
os.Remove("libgo9.h")
}()
}
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo9.a", "./libgo9")
out, err := cmd.CombinedOutput()
t.Logf("%v\n%s", cmd.Args, out)
if err != nil {
t.Fatal(err)
}
checkLineComments(t, "libgo9.h")
checkArchive(t, "libgo9.a")
// build with -O0 so the C compiler won't optimize out the large stack frame
ccArgs := append(cc, "-O0", "-o", "testp9"+exeSuffix, "main9.c", "libgo9.a")
out, err = exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput()
t.Logf("%v\n%s", ccArgs, out)
if err != nil {
t.Fatal(err)
}
argv := cmdToRun("./testp9")
cmd = exec.Command(argv[0], argv[1:]...)
sb := new(strings.Builder)
cmd.Stdout = sb
cmd.Stderr = sb
if err := cmd.Start(); err != nil {
t.Fatal(err)
}
timer := time.AfterFunc(time.Minute,
func() {
t.Error("test program timed out")
cmd.Process.Kill()
},
)
defer timer.Stop()
err = cmd.Wait()
t.Logf("%v\n%s", cmd.Args, sb)
if err != nil {
t.Error(err)
}
}

View File

@ -1,14 +0,0 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "runtime"
import "C"
func main() {}
//export GoF
func GoF() { runtime.GC() }

View File

@ -1,24 +0,0 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "libgo9.h"
void use(int *x) { (*x)++; }
void callGoFWithDeepStack() {
int x[10000];
use(&x[0]);
use(&x[9999]);
GoF();
use(&x[0]);
use(&x[9999]);
}
int main() {
GoF(); // call GoF without using much stack
callGoFWithDeepStack(); // call GoF with a deep stack
}

View File

@ -19,7 +19,6 @@ import "unsafe"
//go:linkname _cgo_yield _cgo_yield
//go:linkname _cgo_pthread_key_created _cgo_pthread_key_created
//go:linkname _cgo_bindm _cgo_bindm
//go:linkname _cgo_getstackbound _cgo_getstackbound
var (
_cgo_init unsafe.Pointer
@ -31,7 +30,6 @@ var (
_cgo_yield unsafe.Pointer
_cgo_pthread_key_created unsafe.Pointer
_cgo_bindm unsafe.Pointer
_cgo_getstackbound unsafe.Pointer
)
// iscgo is set to true by the runtime/cgo package

View File

@ -141,12 +141,3 @@ var _cgo_yield unsafe.Pointer
//go:cgo_export_static _cgo_topofstack
//go:cgo_export_dynamic _cgo_topofstack
// x_cgo_getstackbound gets the thread's C stack size and
// set the G's stack bound based on the stack size.
//go:cgo_import_static x_cgo_getstackbound
//go:linkname x_cgo_getstackbound x_cgo_getstackbound
//go:linkname _cgo_getstackbound _cgo_getstackbound
var x_cgo_getstackbound byte
var _cgo_getstackbound = &x_cgo_getstackbound

View File

@ -1,21 +0,0 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include <pthread.h>
#include "libcgo.h"
void
x_cgo_getstackbound(G *g)
{
void* addr;
size_t size;
pthread_t p;
p = pthread_self();
addr = pthread_get_stackaddr_np(p); // high address (!)
size = pthread_get_stacksize_np(p);
g->stacklo = (uintptr)addr - size;
// NOTE: don't change g->stackhi. We are called from asmcgocall
// which saves the stack depth based on g->stackhi.
}

View File

@ -1,32 +0,0 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build unix && !darwin
#ifndef _GNU_SOURCE // pthread_getattr_np
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include "libcgo.h"
void
x_cgo_getstackbound(G *g)
{
pthread_attr_t attr;
void *addr;
size_t size;
pthread_attr_init(&attr);
#if defined(__GLIBC__) || defined(__sun)
pthread_getattr_np(pthread_self(), &attr); // GNU extension
pthread_attr_getstack(&attr, &addr, &size); // low address
#else
pthread_attr_getstacksize(&attr, &size);
addr = __builtin_frame_address(0) + 4096 - size;
#endif
g->stacklo = (uintptr)addr;
// NOTE: don't change g->stackhi. We are called from asmcgocall
// which saves the stack depth based on g->stackhi.
}

View File

@ -1,7 +0,0 @@
// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "libcgo.h"
void x_cgo_getstackbound(G *g) {} // no-op for now

View File

@ -1889,11 +1889,8 @@ func allocm(pp *p, fn func(), id int64) *m {
// 1. when the callback is done with the m in non-pthread platforms,
// 2. or when the C thread exiting on pthread platforms.
//
// The signal argument indicates whether we're called from a signal
// handler.
//
//go:nosplit
func needm(signal bool) {
func needm() {
if (iscgo || GOOS == "windows") && !cgoHasExtraM {
// Can happen if C/C++ code calls Go from a global ctor.
// Can also happen on Windows if a global ctor uses a
@ -1942,23 +1939,14 @@ func needm(signal bool) {
osSetupTLS(mp)
// Install g (= m->g0) and set the stack bounds
// to match the current stack. If we don't actually know
// to match the current stack. We don't actually know
// how big the stack is, like we don't know how big any
// scheduling stack is, but we assume there's at least 32 kB.
// If we can get a more accurate stack bound from pthread,
// use that.
// scheduling stack is, but we assume there's at least 32 kB,
// which is more than enough for us.
setg(mp.g0)
gp := getg()
gp.stack.hi = getcallersp() + 1024
gp.stack.lo = getcallersp() - 32*1024
if !signal && _cgo_getstackbound != nil {
// Don't adjust if called from the signal handler.
// We are on the signal stack, not the pthread stack.
// (We could get the stack bounds from sigaltstack, but
// we're getting out of the signal handler very soon
// anyway. Not worth it.)
asmcgocall(_cgo_getstackbound, unsafe.Pointer(gp))
}
gp.stackguard0 = gp.stack.lo + _StackGuard
// Should mark we are already in Go now.
@ -1979,7 +1967,7 @@ func needm(signal bool) {
//
//go:nosplit
func needAndBindM() {
needm(false)
needm()
if _cgo_pthread_key_created != nil && *(*uintptr)(_cgo_pthread_key_created) != 0 {
cgoBindM()

View File

@ -585,7 +585,7 @@ func adjustSignalStack(sig uint32, mp *m, gsigStack *gsignalStack) bool {
// sp is not within gsignal stack, g0 stack, or sigaltstack. Bad.
setg(nil)
needm(true)
needm()
if st.ss_flags&_SS_DISABLE != 0 {
noSignalStack(sig)
} else {
@ -1068,7 +1068,7 @@ func badsignal(sig uintptr, c *sigctxt) {
exit(2)
*(*uintptr)(unsafe.Pointer(uintptr(123))) = 2
}
needm(true)
needm()
if !sigsend(uint32(sig)) {
// A foreign thread received the signal sig, and the
// Go code does not want to handle it.