Fix pprof service race condition

pull/3829/head
niklr 3 years ago committed by Leo Chen
parent 7af5cdd864
commit cb273387a7
  1. 13
      api/service/pprof/service.go
  2. 27
      api/service/pprof/service_test.go

@ -50,6 +50,7 @@ var (
initOnce sync.Once
svc = &Service{}
cpuFile *os.File
lock sync.Mutex
)
// NewService creates the new pprof service
@ -75,11 +76,6 @@ func newService(cfg Config) *Service {
}
svc.profiles = profiles
go func() {
utils.Logger().Info().Str("address", cfg.ListenAddr).Msg("starting pprof HTTP service")
http.ListenAndServe(cfg.ListenAddr, nil)
}()
return svc
}
@ -94,6 +90,11 @@ func (s *Service) Start() error {
return err
}
go func() {
utils.Logger().Info().Str("address", s.config.ListenAddr).Msg("starting pprof HTTP service")
http.ListenAndServe(s.config.ListenAddr, nil)
}()
if _, ok := s.profiles[CPU]; ok {
// The nature of the pprof CPU profile is fundamentally different to the other profiles, because it streams output to a file during profiling.
// Thus it has to be started outside of the defined interval.
@ -177,6 +178,8 @@ func saveProfile(profile Profile, dir string) error {
// restartCpuProfile stops the current CPU profile, if any and then starts a new CPU profile. While profiling in the background, the profile will be buffered and written to a file.
func restartCpuProfile(dir string) error {
lock.Lock()
defer lock.Unlock()
stopCpuProfile()
f, err := newTempFile(dir, CPU, ".pb.gz")
if err != nil {

@ -3,10 +3,14 @@ package pprof
import (
"errors"
"fmt"
"math/rand"
"os"
"path/filepath"
"reflect"
"runtime/pprof"
"strings"
"testing"
"time"
)
func TestUnpackProfilesIntoMap(t *testing.T) {
@ -72,6 +76,29 @@ func TestUnpackProfilesIntoMap(t *testing.T) {
}
}
func TestStart(t *testing.T) {
input := &Config{
Enabled: true,
Folder: tempTestDir(),
ProfileNames: []string{"cpu"},
ProfileIntervals: []int{1},
}
defer os.RemoveAll(input.Folder)
s := NewService(*input)
err := s.Start()
if assErr := assertError(err, nil); assErr != nil {
t.Fatal(assErr)
}
time.Sleep(1 * time.Second)
}
func tempTestDir() string {
tempDir := os.TempDir()
testDir := filepath.Join(tempDir, fmt.Sprintf("pprof-service-test-%d-%d", os.Getpid(), rand.Int()))
os.RemoveAll(testDir)
return testDir
}
func assertError(gotErr, expErr error) error {
if (gotErr == nil) != (expErr == nil) {
return fmt.Errorf("error unexpected [%v] / [%v]", gotErr, expErr)

Loading…
Cancel
Save