// +build debug profile package main import ( "fmt" "net/http" _ "net/http/pprof" "os" "github.com/restic/restic/internal/errors" "github.com/restic/restic/internal/repository" "github.com/pkg/profile" ) var ( listenProfile string memProfilePath string cpuProfilePath string traceProfilePath string blockProfilePath string insecure bool ) func init() { f := cmdRoot.PersistentFlags() f.StringVar(&listenProfile, "listen-profile", "", "listen on this `address:port` for memory profiling") f.StringVar(&memProfilePath, "mem-profile", "", "write memory profile to `dir`") f.StringVar(&cpuProfilePath, "cpu-profile", "", "write cpu profile to `dir`") f.StringVar(&traceProfilePath, "trace-profile", "", "write trace to `dir`") f.StringVar(&blockProfilePath, "block-profile", "", "write block profile to `dir`") f.BoolVar(&insecure, "insecure-kdf", false, "use insecure KDF settings") } type fakeTestingTB struct{} func (fakeTestingTB) Logf(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg, args...) } func runDebug() error { if listenProfile != "" { fmt.Fprintf(os.Stderr, "running profile HTTP server on %v\n", listenProfile) go func() { err := http.ListenAndServe(listenProfile, nil) if err != nil { fmt.Fprintf(os.Stderr, "profile HTTP server listen failed: %v\n", err) } }() } profilesEnabled := 0 if memProfilePath != "" { profilesEnabled++ } if cpuProfilePath != "" { profilesEnabled++ } if traceProfilePath != "" { profilesEnabled++ } if blockProfilePath != "" { profilesEnabled++ } if profilesEnabled > 1 { return errors.Fatal("only one profile (memory, CPU, trace, or block) may be activated at the same time") } var prof interface { Stop() } if memProfilePath != "" { prof = profile.Start(profile.Quiet, profile.NoShutdownHook, profile.MemProfile, profile.ProfilePath(memProfilePath)) } else if cpuProfilePath != "" { prof = profile.Start(profile.Quiet, profile.NoShutdownHook, profile.CPUProfile, profile.ProfilePath(cpuProfilePath)) } else if traceProfilePath != "" { prof = profile.Start(profile.Quiet, profile.NoShutdownHook, profile.TraceProfile, profile.ProfilePath(traceProfilePath)) } else if blockProfilePath != "" { prof = profile.Start(profile.Quiet, profile.NoShutdownHook, profile.BlockProfile, profile.ProfilePath(blockProfilePath)) } if prof != nil { AddCleanupHandler(func() error { prof.Stop() return nil }) } if insecure { repository.TestUseLowSecurityKDFParameters(fakeTestingTB{}) } return nil }