-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
What version of Go are you using (go version)?
$ go version go version devel go1.22-6dd7462a04 Fri Oct 13 17:10:31 2023 +0000 darwin/arm64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go envGO111MODULE='on' GOARCH='arm64' GOBIN='' GOCACHE='/Users/myname/Library/Caches/go-build' GOENV='/Users/myname/Library/Application Support/go/env' GOEXE='' GOEXPERIMENT='' GOFLAGS='' GOHOSTARCH='arm64' GOHOSTOS='darwin' GOINSECURE='' GOMODCACHE='/Users/myname/go/pkg/mod' GONOPROXY='' GONOSUMDB='' GOOS='darwin' GOPATH='/Users/myname/go' GOPRIVATE='' GOPROXY='' GOROOT='/Users/myname/mypath/go' GOSUMDB='off' GOTMPDIR='' GOTOOLCHAIN='auto' GOTOOLDIR='/Users/myname/mypath/go/pkg/tool/darwin_arm64' GOVCS='' GOVERSION='devel go1.22-6dd7462a04 Fri Oct 13 17:10:31 2023 +0000' # I compiled it myself, it can be ignored and has nothing to do with the version. GCCGO='gccgo' AR='ar' CC='clang' CXX='clang++' CGO_ENABLED='1' GOMOD='/Users/myname/mypath/go/src/go.mod' GOWORK='' CGO_CFLAGS='-O2 -g' CGO_CPPFLAGS='' CGO_CXXFLAGS='-O2 -g' CGO_FFLAGS='-O2 -g' CGO_LDFLAGS='-O2 -g' PKG_CONFIG='pkg-config' GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/9t/839s3jmj73bcgyp5x_xh3gw00000gn/T/go-build3891298911=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
I helped a colleague write a sample code to obtain the pprof file when the memory exceeds the threshold.
package main
import (
"fmt"
"os"
"runtime"
"runtime/pprof"
"time"
)
func main() {
ticker := time.NewTicker(10 * time.Second)
go func() {
for {
time.Sleep(1e9)
var m runtime.MemStats
runtime.ReadMemStats(&m)
memUsage := m.Sys / 1024 / 1024
if memUsage > 1024 {
fmt.Printf("memory usage more than 1GB:%dMB\n", memUsage)
// save pprof file
filepath := "/xxx/yyy/path/mem" + "." + strconv.Itoa(int(time.Now().Unix()))
f, err := os.Create(filepath)
if err != nil {
fmt.Println("err1:", err)
}
defer f.Close()
if err2 := pprof.WriteHeapProfile(f); err2 != nil {
fmt.Println("err2:", err2)
}
fmt.Println("pprof data has saved in:", filepath)
} else {
fmt.Printf(memory usage is:%dMB\n", memUsage)
}
}
}()
for {
select {
case <-ticker.C:
var a = make([]byte, 1073741824)
_ = a
fmt.Println("ticker:", time.Now())
}
}
select {}
}I tested it locally and everything was fine. He made certain modifications and then released it to the production environment. When the memory surge occurred, this program obtained the pprof file as expected, but what was confusing and surprising was that when using go tool pprof thefile, an error was reported:
Fetching profile over HTTP from http://mem_2023-11-01_14:23:16/debug/pprof/profile
profile.pprof.2023-11-03_14:23:16: Get "http://mem_2023-11-01_14:23:16/debug/pprof/profile": dial tcp: lookup mem_2023-11-01_14:23: no such host
I spent a lot of time trying to research, and one of his modifications was to change the timestamp in the file path to time.Now().Format("2006-01-02_15:04:05") in order to be more intuitive.
That is
filepath := "/xxx/yyy/path/mem" + "." + strconv.Itoa(int(time.Now().Unix())) ---> filepath := "/xxx/yyy/path /mem" + "." + time.Now().Format("2006-01-02_15:04:05")
After adding debug information several times, it was found that it was the adjustURL method in internal/driver/fetch.go. Because the file name contained a colon, url.Parse parsed the file path into a url. . .
This is confusing and counter-intuitive. After many experiments, I think we can consider determining whether there is a file with the same name in the directory. If so, treat it as a file instead of a URL.
(We only need to consider the case of executing go tool pprof in the directory where the profile is located. In the case of go tool pprof a/b/mem_pprof_file_2006_01_02_15:04:05, it will not be recognized as a URL now)
What did you expect to see?
I want to be able to use pprof normally without renaming the file
What did you see instead?
Fetching profile over HTTP from http://mem_2023-11-01_14:23:16/debug/pprof/profile
profile.pprof.2023-11-03_14:23:16: Get "http://mem_2023-11-01_14:23:16/debug/pprof/profile": dial tcp: lookup mem_2023-11-01_14:23: no such host
Metadata
Metadata
Assignees
Labels
Type
Projects
Status