runtime: consolidate some low-level error reporting

Use a single writeErrStr function. Avoid using global variables.
Use a single version of some error messages rather than duplicating
the messages in OS-specific files.

Change-Id: If259fbe78faf797f0a21337d14472160ca03efa0
Reviewed-on: https://go-review.googlesource.com/c/go/+/447055
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Ian Lance Taylor 2022-11-01 12:33:59 -07:00 committed by Gopher Robot
parent fbf763fd1d
commit 79d9b395ad
9 changed files with 40 additions and 53 deletions

View File

@ -111,17 +111,17 @@ func newosproc0(stacksize uintptr, fn *funcDescriptor) {
)
if pthread_attr_init(&attr) != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
if pthread_attr_setstacksize(&attr, threadStackSize) != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
@ -140,14 +140,12 @@ func newosproc0(stacksize uintptr, fn *funcDescriptor) {
}
sigprocmask(_SIG_SETMASK, &oset, nil)
if ret != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
}
var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
// Called to do synchronous initialization of Go code built with
// -buildmode=c-archive or -buildmode=c-shared.
// None of the Go runtime is initialized.

View File

@ -208,21 +208,21 @@ func newosproc(mp *m) {
var err int32
err = pthread_attr_init(&attr)
if err != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
// Find out OS stack size for our own stack guard.
var stacksize uintptr
if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
mp.g0.stack.hi = stacksize // for mstart
// Tell the pthread library we won't join with this thread.
if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
@ -233,7 +233,7 @@ func newosproc(mp *m) {
err = pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
sigprocmask(_SIG_SETMASK, &oset, nil)
if err != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
}
@ -253,7 +253,7 @@ func newosproc0(stacksize uintptr, fn uintptr) {
var err int32
err = pthread_attr_init(&attr)
if err != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
@ -263,7 +263,7 @@ func newosproc0(stacksize uintptr, fn uintptr) {
// we use the OS default stack size instead of the suggestion.
// Find out that stack size for our own stack guard.
if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
g0.stack.hi = stacksize // for mstart
@ -271,7 +271,7 @@ func newosproc0(stacksize uintptr, fn uintptr) {
// Tell the pthread library we won't join with this thread.
if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
@ -282,14 +282,11 @@ func newosproc0(stacksize uintptr, fn uintptr) {
err = pthread_create(&attr, fn, nil)
sigprocmask(_SIG_SETMASK, &oset, nil)
if err != 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
}
var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
// Called to do synchronous initialization of Go code built with
// -buildmode=c-archive or -buildmode=c-shared.
// None of the Go runtime is initialized.

View File

@ -227,7 +227,7 @@ func newosproc(mp *m) {
func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
stack := sysAlloc(stacksize, &memstats.stacks_sys)
if stack == nil {
write(2, unsafe.Pointer(&failallocatestack[0]), int32(len(failallocatestack)))
writeErrStr(failallocatestack)
exit(1)
}
// This code "knows" it's being called once from the library
@ -252,14 +252,11 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
ret := thr_new(&param, int32(unsafe.Sizeof(param)))
sigprocmask(_SIG_SETMASK, &oset, nil)
if ret < 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
}
var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
// Called to do synchronous initialization of Go code built with
// -buildmode=c-archive or -buildmode=c-shared.
// None of the Go runtime is initialized.

View File

@ -194,19 +194,16 @@ func newosproc(mp *m) {
func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
stack := sysAlloc(stacksize, &memstats.stacks_sys)
if stack == nil {
write(2, unsafe.Pointer(&failallocatestack[0]), int32(len(failallocatestack)))
writeErrStr(failallocatestack)
exit(1)
}
ret := clone(cloneFlags, unsafe.Pointer(uintptr(stack)+stacksize), nil, nil, fn)
if ret < 0 {
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
writeErrStr(failthreadcreate)
exit(1)
}
}
var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
const (
_AT_NULL = 0 // End of vector
_AT_PAGESZ = 6 // System physical page size

View File

@ -11,8 +11,6 @@ import (
"unsafe"
)
var failThreadCreate = []byte("runtime: failed to create new OS thread\n")
// mstart_stub provides glue code to call mstart from pthread_create.
func mstart_stub()
@ -27,21 +25,21 @@ func newosproc(mp *m) {
// Initialize an attribute object.
var attr pthreadattr
if err := pthread_attr_init(&attr); err != 0 {
write(2, unsafe.Pointer(&failThreadCreate[0]), int32(len(failThreadCreate)))
writeErrStr(failthreadcreate)
exit(1)
}
// Find out OS stack size for our own stack guard.
var stacksize uintptr
if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
write(2, unsafe.Pointer(&failThreadCreate[0]), int32(len(failThreadCreate)))
writeErrStr(failthreadcreate)
exit(1)
}
mp.g0.stack.hi = stacksize // for mstart
// Tell the pthread library we won't join with this thread.
if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
write(2, unsafe.Pointer(&failThreadCreate[0]), int32(len(failThreadCreate)))
writeErrStr(failthreadcreate)
exit(1)
}
@ -52,7 +50,7 @@ func newosproc(mp *m) {
err := pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
sigprocmask(_SIG_SETMASK, &oset, nil)
if err != 0 {
write(2, unsafe.Pointer(&failThreadCreate[0]), int32(len(failThreadCreate)))
writeErrStr(failthreadcreate)
exit(1)
}

View File

@ -494,22 +494,16 @@ func badreflectcall() {
panic(plainError("arg size to reflect.call more than 1GB"))
}
var badmorestackg0Msg = "fatal: morestack on g0\n"
//go:nosplit
//go:nowritebarrierrec
func badmorestackg0() {
sp := stringStructOf(&badmorestackg0Msg)
write(2, sp.str, int32(sp.len))
writeErrStr("fatal: morestack on g0\n")
}
var badmorestackgsignalMsg = "fatal: morestack on gsignal\n"
//go:nosplit
//go:nowritebarrierrec
func badmorestackgsignal() {
sp := stringStructOf(&badmorestackgsignalMsg)
write(2, sp.str, int32(sp.len))
writeErrStr("fatal: morestack on gsignal\n")
}
//go:nosplit
@ -1890,7 +1884,7 @@ func needm() {
// for details.
//
// Can not throw, because scheduler is not initialized yet.
write(2, unsafe.Pointer(&earlycgocallback[0]), int32(len(earlycgocallback)))
writeErrStr("fatal error: cgo callback before cgo call\n")
exit(1)
}
@ -1950,8 +1944,6 @@ func needm() {
sched.ngsys.Add(-1)
}
var earlycgocallback = []byte("fatal error: cgo callback before cgo call\n")
// newextram allocates m's and puts them on the extra list.
// It is called with a working local m, so that it can do things
// like call schedlock and allocate.
@ -2144,6 +2136,13 @@ var (
execLock rwmutex
)
// These errors are reported (via writeErrStr) by some OS-specific
// versions of newosproc and newosproc0.
const (
failthreadcreate = "runtime: failed to create new OS thread\n"
failallocatestack = "runtime: failed to allocate stack for the new OS thread\n"
)
// newmHandoff contains a list of m structures that need new OS threads.
// This is used by newm in situations where newm itself can't safely
// start an OS thread.

View File

@ -6,7 +6,7 @@ package runtime
import (
"runtime/internal/atomic"
_ "unsafe" // for go:linkname
"unsafe"
)
//go:generate go run wincallback.go
@ -93,3 +93,10 @@ func syscall_runtimeUnsetenv(key string) {
godebugenv.Store(nil)
}
}
// writeErrStr writes a string to descriptor 2.
//
//go:nosplit
func writeErrStr(s string) {
write(2, unsafe.Pointer(unsafe.StringData(s)), int32(len(s)))
}

View File

@ -1039,8 +1039,6 @@ func signalDuringFork(sig uint32) {
throw("signal received during fork")
}
var badginsignalMsg = "fatal: bad g in signal handler\n"
// This runs on a foreign stack, without an m or a g. No stack split.
//
//go:nosplit
@ -1051,8 +1049,7 @@ func badsignal(sig uintptr, c *sigctxt) {
// There is no extra M. needm will not be able to grab
// an M. Instead of hanging, just crash.
// Cannot call split-stack function as there is no G.
s := stringStructOf(&badginsignalMsg)
write(2, s.str, int32(s.len))
writeErrStr("fatal: bad g in signal handler\n")
exit(2)
*(*uintptr)(unsafe.Pointer(uintptr(123))) = 2
}

View File

@ -59,13 +59,10 @@ func mcall(fn func(*g))
//go:noescape
func systemstack(fn func())
var badsystemstackMsg = "fatal: systemstack called from unexpected goroutine"
//go:nosplit
//go:nowritebarrierrec
func badsystemstack() {
sp := stringStructOf(&badsystemstackMsg)
write(2, sp.str, int32(sp.len))
writeErrStr("fatal: systemstack called from unexpected goroutine")
}
// memclrNoHeapPointers clears n bytes starting at ptr.