github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/pprof/proto_windows.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package pprof 6 7 import ( 8 "errors" 9 "internal/syscall/windows" 10 "syscall" 11 ) 12 13 // readMapping adds memory mapping information to the profile. 14 func (b *profileBuilder) readMapping() { 15 snap, err := createModuleSnapshot() 16 if err != nil { 17 // pprof expects a map entry, so fake one, when we haven't added anything yet. 18 b.addMappingEntry(0, 0, 0, "", "", true) 19 return 20 } 21 defer func() { _ = syscall.CloseHandle(snap) }() 22 23 var module windows.ModuleEntry32 24 module.Size = uint32(windows.SizeofModuleEntry32) 25 err = windows.Module32First(snap, &module) 26 if err != nil { 27 // pprof expects a map entry, so fake one, when we haven't added anything yet. 28 b.addMappingEntry(0, 0, 0, "", "", true) 29 return 30 } 31 for err == nil { 32 exe := syscall.UTF16ToString(module.ExePath[:]) 33 b.addMappingEntry( 34 uint64(module.ModBaseAddr), 35 uint64(module.ModBaseAddr)+uint64(module.ModBaseSize), 36 0, 37 exe, 38 peBuildID(exe), 39 false, 40 ) 41 err = windows.Module32Next(snap, &module) 42 } 43 } 44 45 func readMainModuleMapping() (start, end uint64, err error) { 46 snap, err := createModuleSnapshot() 47 if err != nil { 48 return 0, 0, err 49 } 50 defer func() { _ = syscall.CloseHandle(snap) }() 51 52 var module windows.ModuleEntry32 53 module.Size = uint32(windows.SizeofModuleEntry32) 54 err = windows.Module32First(snap, &module) 55 if err != nil { 56 return 0, 0, err 57 } 58 59 return uint64(module.ModBaseAddr), uint64(module.ModBaseAddr) + uint64(module.ModBaseSize), nil 60 } 61 62 func createModuleSnapshot() (syscall.Handle, error) { 63 for { 64 snap, err := syscall.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE|windows.TH32CS_SNAPMODULE32, uint32(syscall.Getpid())) 65 var errno syscall.Errno 66 if err != nil && errors.As(err, &errno) && errno == windows.ERROR_BAD_LENGTH { 67 // When CreateToolhelp32Snapshot(SNAPMODULE|SNAPMODULE32, ...) fails 68 // with ERROR_BAD_LENGTH then it should be retried until it succeeds. 69 continue 70 } 71 return snap, err 72 } 73 }