golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.97k stars 17.66k forks source link

runtime: cannot run go.exe on Windows Server 2016 #29885

Closed huangyezuojia closed 1 year ago

huangyezuojia commented 5 years ago

What version of Go are you using (go version)?

$ go 1.11

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
go  can not run

What did you do?

only run go.exe

What did you expect to see?

run success

What did you see instead?

D:\go\go1_11\go\src\runtime\sys_windows_amd64.s:60 is lasterror

huangyezuojia commented 5 years ago

more info:

cpu is intel xeon(R) silver 4110 cpu @ 2.10GHZ

huangyezuojia commented 5 years ago

maybe is cpu reason?

D:\go\go1_11\go\src\runtime\sys_windows_amd64.s:60 loadregs: // Load first 4 args into correspondent registers. MOVQ 0(SI), CX MOVQ 8(SI), DX MOVQ 16(SI), R8 MOVQ 24(SI), R9 // Floating point arguments are passed in the XMM // registers. Set them here in case any of the arguments // are floating point values. For details see // https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx MOVQ CX, X0 MOVQ DX, X1 MOVQ R8, X2 MOVQ R9, X3

// Call stdcall function.
CALL    AX

ADDQ    $(maxargs*8), SP

// Return result.
POPQ    CX
MOVQ    AX, libcall_r1(CX)

// GetLastError().
MOVQ    0x30(GS), DI
MOVL    0x68(DI), AX
MOVQ    AX, libcall_err(CX)

RET
huangyezuojia commented 5 years ago

more info:

last call function: // grow allocates a new empty span from the heap and initializes it for c's size class. func (c mcentral) grow() mspan { npages := uintptr(class_to_allocnpages[c.spanclass.sizeclass()]) size := uintptr(class_to_size[c.spanclass.sizeclass()]) n := (npages << _PageShift) / size

s := mheap_.alloc(npages, c.spanclass, false, true)
if s == nil {
    return nil
}

p := s.base()
s.limit = p + size*n

heapBitsForAddr(s.base()).initSpan(s)
return s

}

huangyezuojia commented 5 years ago

func (h mheap) alloc(npage uintptr, spanclass spanClass, large bool, needzero bool) mspan { // Don't do any operations that lock the heap on the G stack. // It might trigger stack growth, and the stack growth code needs // to be able to allocate heap. var s *mspan systemstack(func() { s = h.alloc_m(npage, spanclass, large) })

if s != nil {
    if needzero && s.needzero != 0 {
        memclrNoHeapPointers(unsafe.Pointer(s.base()), s.npages<<_PageShift)
    }
    s.needzero = 0
}
return s

}

ianlancetaylor commented 5 years ago

What precisely did you do? What precisely did you see?

huangyezuojia commented 5 years ago

What precisely did you do?

I just download the https://dl.google.com/go/go1.11.4.windows-amd64.zip, then run at window server 2016

the server's cpu is intel xeon(R) silver 4110 cpu @ 2.10GHZ

What precisely did you see?

similar to these url: https://groups.google.com/forum/m/#!topic/golang-nuts/jrDfbwx2BSo https://github.com/golang/go/issues/21060

Exception 0xc0000005 0x8 0x0 0x0 PC=0x0

runtime.asmstdcall(0x8fdd8, 0x40ee8d, 0x10f4000, 0x0, 0x100000044f980, 0x20, 0x11, 0x10f4000, 0x44f8c0, 0x10f0000, ...) c:/go/src/runtime/sys_windows_amd64.s:60 +0x5e fp=0x8fd80 sp=0x8fd70

my server is a remote server , i have not the right to copy output but i remember the stack is below and some source code:

top0: Exception PC=0x0 top1: func (c mcentral) grow() top2: v, _, shouldhelpgc = c.nextFree(tinySpanClass) top3: func mallocgc(size uintptr, typ _type, needzero bool) unsafe.Pointer top4: func newobject(typ *_type) unsafe.Pointer {

huangyezuojia commented 5 years ago

maybe the function have problem?

This function is suspicious D:\go\go\src\runtime\mheap.go

func (h mheap) alloc(npage uintptr, spanclass spanClass, large bool, needzero bool) mspan { // Don't do any operations that lock the heap on the G stack. // It might trigger stack growth, and the stack growth code needs // to be able to allocate heap. var s *mspan systemstack(func() { s = h.alloc_m(npage, spanclass, large) })

if s != nil { if needzero && s.needzero != 0 { memclrNoHeapPointers(unsafe.Pointer(s.base()), s.npages<<_PageShift) } s.needzero = 0 } return s }

D:\go\go\src\runtime\asm_amd64.s

// func systemstack(fn func()) TEXT runtime·systemstack(SB), NOSPLIT, $0-8

huangyezuojia commented 5 years ago

go exe

another crash, need help

ianlancetaylor commented 5 years ago

Please tell us precisely what you did. List the exact commands that you ran. Don't just say "run at window server 2016". Tell us exactly what you did. Thanks.

huangyezuojia commented 5 years ago

Please tell us precisely what you did. List the exact commands that you ran. Don't just say "run at window server 2016". Tell us exactly what you did. Thanks.

decompress go1.11.4.windows-amd64.zip and run go.exe i found some doubtful point

SUBQ $(maxargs*8), SP can align 16byte?

code at D:\go\go_1_11_5_src\go\src\runtime\sys_windows_amd64.s

// maxargs should be divisible by 2, as Windows stack // must be kept 16-byte aligned on syscall entry.

define maxargs 16

// void runtime·asmstdcall(void *c); TEXT runtime·asmstdcall(SB),NOSPLIT|NOFRAME,$0 // asmcgocall will put first argument into CX. PUSHQ CX // save for later MOVQ libcall_fn(CX), AX MOVQ libcall_args(CX), SI MOVQ libcall_n(CX), CX

// SetLastError(0).
MOVQ    0x30(GS), DI
MOVL    $0, 0x68(DI)

SUBQ    $(maxargs*8), SP    // room for args

...

huangyezuojia commented 5 years ago

IMG20190308180924

huangyezuojia commented 5 years ago

i found the reason:

os_windows.go have not found a function _RtlGenRandom

code:

func loadOptionalSyscalls() {
    var kernel32dll = []byte("kernel32.dll\000")
    k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0])))
    if k32 == 0 {
        throw("kernel32.dll not found")
    }
    _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000"))
    _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
    _GetQueuedCompletionStatusEx = windowsFindfunc(k32, []byte("GetQueuedCompletionStatusEx\000"))
    _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000"))

    var advapi32dll = []byte("advapi32.dll\000")
    a32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&advapi32dll[0])))
    if a32 == 0 {
        throw("advapi32.dll not found")
    }
    _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
...
}
qmuntal commented 1 year ago

CL 536235 dropped RtlGenRandom in favor of ProcessPrng, so this failure mode is no longer possible.