mirror of
https://github.com/golang/go
synced 2024-11-19 12:34:47 -07:00
cmd/link: restore windows stack commit size back to 4KB
CL 49331 increased windows stack commit size to 2MB by mistake. Revert that change. Fixes #22439 Change-Id: I919e549e87da326f4ba45890b4d32f6d7046186f Reviewed-on: https://go-review.googlesource.com/74490 TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
25159d3af9
commit
923299a6b8
@ -848,7 +848,14 @@ func (f *peFile) writeOptionalHeader(ctxt *Link) {
|
||||
// runtime/cgo/gcc_windows_{386,amd64}.c and the correspondent
|
||||
// CreateThread parameter in runtime.newosproc.
|
||||
oh64.SizeOfStackReserve = 0x00200000
|
||||
oh64.SizeOfStackCommit = 0x00200000 - 0x2000 // account for 2 guard pages
|
||||
if !iscgo {
|
||||
oh64.SizeOfStackCommit = 0x00001000
|
||||
} else {
|
||||
// TODO(brainman): Maybe remove optional header writing altogether for cgo.
|
||||
// For cgo it is the external linker that is building final executable.
|
||||
// And it probably does not use any information stored in optional header.
|
||||
oh64.SizeOfStackCommit = 0x00200000 - 0x2000 // account for 2 guard pages
|
||||
}
|
||||
|
||||
// 32-bit is trickier since there much less address space to
|
||||
// work with. Here we use large stacks only in cgo binaries as
|
||||
@ -858,7 +865,7 @@ func (f *peFile) writeOptionalHeader(ctxt *Link) {
|
||||
oh.SizeOfStackCommit = 0x00001000
|
||||
} else {
|
||||
oh.SizeOfStackReserve = 0x00100000
|
||||
oh.SizeOfStackCommit = 0x00100000 - 0x2000
|
||||
oh.SizeOfStackCommit = 0x00100000 - 0x2000 // account for 2 guard pages
|
||||
}
|
||||
|
||||
oh64.SizeOfHeapReserve = 0x00100000
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
package windows
|
||||
|
||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go security_windows.go
|
||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go security_windows.go psapi_windows.go
|
||||
|
20
src/internal/syscall/windows/psapi_windows.go
Normal file
20
src/internal/syscall/windows/psapi_windows.go
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2017 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 windows
|
||||
|
||||
type PROCESS_MEMORY_COUNTERS struct {
|
||||
CB uint32
|
||||
PageFaultCount uint32
|
||||
PeakWorkingSetSize uintptr
|
||||
WorkingSetSize uintptr
|
||||
QuotaPeakPagedPoolUsage uintptr
|
||||
QuotaPagedPoolUsage uintptr
|
||||
QuotaPeakNonPagedPoolUsage uintptr
|
||||
QuotaNonPagedPoolUsage uintptr
|
||||
PagefileUsage uintptr
|
||||
PeakPagefileUsage uintptr
|
||||
}
|
||||
|
||||
//sys GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) = psapi.GetProcessMemoryInfo
|
@ -40,6 +40,7 @@ var (
|
||||
modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
|
||||
modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
|
||||
modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
|
||||
modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
|
||||
|
||||
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
|
||||
procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
|
||||
@ -57,6 +58,7 @@ var (
|
||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
||||
procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
|
||||
)
|
||||
|
||||
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
|
||||
@ -243,3 +245,15 @@ func adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newst
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(memCounters)), uintptr(cb))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@ -452,3 +453,20 @@ func TestCgoLockOSThreadExit(t *testing.T) {
|
||||
t.Parallel()
|
||||
testLockOSThreadExit(t, "testprogcgo")
|
||||
}
|
||||
|
||||
func testWindowsStackMemory(t *testing.T, o string) {
|
||||
stackUsage, err := strconv.Atoi(o)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read stack usage: %v", err)
|
||||
}
|
||||
if expected, got := 100<<10, stackUsage; got > expected {
|
||||
t.Fatalf("expected < %d bytes of memory per thread, got %d", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWindowsStackMemoryCgo(t *testing.T) {
|
||||
if runtime.GOOS != "windows" {
|
||||
t.Skip("skipping windows specific test")
|
||||
}
|
||||
testWindowsStackMemory(t, runTestProg(t, "testprogcgo", "StackMemory"))
|
||||
}
|
||||
|
@ -537,6 +537,10 @@ func TestWERDialogue(t *testing.T) {
|
||||
cmd.CombinedOutput()
|
||||
}
|
||||
|
||||
func TestWindowsStackMemory(t *testing.T) {
|
||||
testWindowsStackMemory(t, runTestProg(t, "testprog", "StackMemory"))
|
||||
}
|
||||
|
||||
var used byte
|
||||
|
||||
func use(buf []byte) {
|
||||
|
45
src/runtime/testdata/testprog/syscall_windows.go
vendored
45
src/runtime/testdata/testprog/syscall_windows.go
vendored
@ -4,11 +4,18 @@
|
||||
|
||||
package main
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"internal/syscall/windows"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("RaiseException", RaiseException)
|
||||
register("ZeroDivisionException", ZeroDivisionException)
|
||||
register("StackMemory", StackMemory)
|
||||
}
|
||||
|
||||
func RaiseException() {
|
||||
@ -25,3 +32,39 @@ func ZeroDivisionException() {
|
||||
z := x / y
|
||||
println(z)
|
||||
}
|
||||
|
||||
func getPagefileUsage() (uintptr, error) {
|
||||
p, err := syscall.GetCurrentProcess()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var m windows.PROCESS_MEMORY_COUNTERS
|
||||
err = windows.GetProcessMemoryInfo(p, &m, uint32(unsafe.Sizeof(m)))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return m.PagefileUsage, nil
|
||||
}
|
||||
|
||||
func StackMemory() {
|
||||
mem1, err := getPagefileUsage()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
const threadCount = 100
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < threadCount; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
runtime.LockOSThread()
|
||||
wg.Done()
|
||||
select {}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
mem2, err := getPagefileUsage()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
print((mem2 - mem1) / threadCount)
|
||||
}
|
||||
|
54
src/runtime/testdata/testprogcgo/stack_windows.go
vendored
Normal file
54
src/runtime/testdata/testprogcgo/stack_windows.go
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2015 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 "C"
|
||||
import (
|
||||
"internal/syscall/windows"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("StackMemory", StackMemory)
|
||||
}
|
||||
|
||||
func getPagefileUsage() (uintptr, error) {
|
||||
p, err := syscall.GetCurrentProcess()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var m windows.PROCESS_MEMORY_COUNTERS
|
||||
err = windows.GetProcessMemoryInfo(p, &m, uint32(unsafe.Sizeof(m)))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return m.PagefileUsage, nil
|
||||
}
|
||||
|
||||
func StackMemory() {
|
||||
mem1, err := getPagefileUsage()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
const threadCount = 100
|
||||
var wg sync.WaitGroup
|
||||
for i := 0; i < threadCount; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
runtime.LockOSThread()
|
||||
wg.Done()
|
||||
select {}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
mem2, err := getPagefileUsage()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
print((mem2 - mem1) / threadCount)
|
||||
}
|
Loading…
Reference in New Issue
Block a user