1
0
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:
Alex Brainman 2017-10-30 20:00:54 +11:00
parent 25159d3af9
commit 923299a6b8
8 changed files with 164 additions and 4 deletions

View File

@ -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

View File

@ -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

View 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

View File

@ -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
}

View File

@ -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"))
}

View File

@ -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) {

View File

@ -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)
}

View 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)
}