From c00ff65d016c07f7feb188ca0458ae3bae0f1532 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 5 Jun 2019 12:31:42 -0400 Subject: [PATCH] runtime: use default system stack size, not 64 kB, on non-cgo macOS At least one libc call we make (res_search, which calls _mdns_query and then mdns_item_call) pushes a 64 kB stack frame onto the stack. Then it faults on the guard page. Use the default system stack size, under the assumption that the C code being called is compatible with that stack size. For #31705. Change-Id: I1b0bfc2e54043c49f0709255988ef920ce30ee82 Reviewed-on: https://go-review.googlesource.com/c/go/+/180779 Run-TryBot: Russ Cox Reviewed-by: Ian Lance Taylor --- src/runtime/os_darwin.go | 19 ++++++++++++------- src/runtime/sys_darwin.go | 8 ++++---- src/runtime/sys_darwin_386.s | 4 ++-- src/runtime/sys_darwin_amd64.s | 4 ++-- src/runtime/sys_darwin_arm.s | 2 +- src/runtime/sys_darwin_arm64.s | 4 ++-- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index 18c15ad89e..819aaaca70 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -145,14 +145,14 @@ func newosproc(mp *m) { exit(1) } - // Set the stack size we want to use. 64KB for now. - // TODO: just use OS default size? - const stackSize = 1 << 16 - if pthread_attr_setstacksize(&attr, stackSize) != 0 { + // 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))) exit(1) } - //mSysStatInc(&memstats.stacks_sys, stackSize) //TODO: do this? + mp.g0.stack.hi = stacksize // for mstart + //mSysStatInc(&memstats.stacks_sys, stacksize) //TODO: do this? // Tell the pthread library we won't join with this thread. if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 { @@ -191,11 +191,16 @@ func newosproc0(stacksize uintptr, fn uintptr) { exit(1) } - // Set the stack we want to use. - if pthread_attr_setstacksize(&attr, stacksize) != 0 { + // The caller passes in a suggested stack size, + // from when we allocated the stack and thread ourselves, + // without libpthread. Now that we're using libpthread, + // 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))) exit(1) } + g0.stack.hi = stacksize // for mstart mSysStatInc(&memstats.stacks_sys, stacksize) // Tell the pthread library we won't join with this thread. diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go index 434fa5f588..0bf17c47af 100644 --- a/src/runtime/sys_darwin.go +++ b/src/runtime/sys_darwin.go @@ -128,10 +128,10 @@ func pthread_attr_init_trampoline() //go:nosplit //go:cgo_unsafe_args -func pthread_attr_setstacksize(attr *pthreadattr, size uintptr) int32 { - return libcCall(unsafe.Pointer(funcPC(pthread_attr_setstacksize_trampoline)), unsafe.Pointer(&attr)) +func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 { + return libcCall(unsafe.Pointer(funcPC(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr)) } -func pthread_attr_setstacksize_trampoline() +func pthread_attr_getstacksize_trampoline() //go:nosplit //go:cgo_unsafe_args @@ -396,7 +396,7 @@ func closeonexec(fd int32) { // in a system library, with the libc_ prefix missing. //go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib" -//go:cgo_import_dynamic libc_pthread_attr_setstacksize pthread_attr_setstacksize "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic libc_pthread_attr_getstacksize pthread_attr_getstacksize "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_pthread_create pthread_create "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib" diff --git a/src/runtime/sys_darwin_386.s b/src/runtime/sys_darwin_386.s index d318509e0a..9a0b3607c2 100644 --- a/src/runtime/sys_darwin_386.s +++ b/src/runtime/sys_darwin_386.s @@ -474,7 +474,7 @@ TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 POPL BP RET -TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0 +TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 PUSHL BP MOVL SP, BP SUBL $8, SP @@ -483,7 +483,7 @@ TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0 MOVL AX, 0(SP) MOVL 4(CX), AX // arg 2 size MOVL AX, 4(SP) - CALL libc_pthread_attr_setstacksize(SB) + CALL libc_pthread_attr_getstacksize(SB) MOVL BP, SP POPL BP RET diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s index 934c510b88..016b056eb3 100644 --- a/src/runtime/sys_darwin_amd64.s +++ b/src/runtime/sys_darwin_amd64.s @@ -443,12 +443,12 @@ TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 POPQ BP RET -TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0 +TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 PUSHQ BP MOVQ SP, BP MOVQ 8(DI), SI // arg 2 size MOVQ 0(DI), DI // arg 1 attr - CALL libc_pthread_attr_setstacksize(SB) + CALL libc_pthread_attr_getstacksize(SB) POPQ BP RET diff --git a/src/runtime/sys_darwin_arm.s b/src/runtime/sys_darwin_arm.s index 6c3fa0739d..82470bc4df 100644 --- a/src/runtime/sys_darwin_arm.s +++ b/src/runtime/sys_darwin_arm.s @@ -323,7 +323,7 @@ TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 BL libc_exit(SB) RET -TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0 +TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 MOVW $46, R0 BL libc_exit(SB) RET diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s index 79dd009f6f..af03af37bb 100644 --- a/src/runtime/sys_darwin_arm64.s +++ b/src/runtime/sys_darwin_arm64.s @@ -382,10 +382,10 @@ TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 BL libc_pthread_attr_init(SB) RET -TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0 +TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 MOVD 8(R0), R1 // arg 2 size MOVD 0(R0), R0 // arg 1 attr - BL libc_pthread_attr_setstacksize(SB) + BL libc_pthread_attr_getstacksize(SB) RET TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 -- 2.50.0