@@ -984,57 +984,87 @@ func (f doneFn) Stop(b testing.TB) {
984984}
985985
986986func startAllocsProfile (b testing.TB ) doneFn {
987- out := benchmemFile (b )
988- if out == "" {
989- return func (tb testing.TB ) {}
987+ outAllocs := testProfileFile (b , "memprofile" )
988+ diffAllocs := diffProfile (b , func () []byte {
989+ if outAllocs == "" {
990+ return nil
991+ }
992+ p := runtimepprof .Lookup ("allocs" )
993+ var buf bytes.Buffer
994+
995+ runtime .GC ()
996+ require .NoError (b , p .WriteTo (& buf , 0 ))
997+
998+ return buf .Bytes ()
999+ })
1000+
1001+ outMutex := testProfileFile (b , "mutexprofile" )
1002+ diffMutex := diffProfile (b , func () []byte {
1003+ if outMutex == "" {
1004+ return nil
1005+ }
1006+ p := runtimepprof .Lookup ("mutex" )
1007+ var buf bytes.Buffer
1008+ require .NoError (b , p .WriteTo (& buf , 0 ))
1009+ return buf .Bytes ()
1010+ })
1011+
1012+ return func (b testing.TB ) {
1013+ if sl := diffAllocs (b ); len (sl ) > 0 {
1014+ require .NoError (b , os .WriteFile (outAllocs , sl , 0644 ))
1015+ }
1016+ if sl := diffMutex (b ); len (sl ) > 0 {
1017+ require .NoError (b , os .WriteFile (outMutex , sl , 0644 ))
1018+ }
9901019 }
1020+ }
9911021
1022+ func diffProfile (b testing.TB , take func () []byte ) func (testing.TB ) []byte {
9921023 // The below is essentially cribbed from pprof.go in net/http/pprof.
993- p := runtimepprof .Lookup ("allocs" )
994- var buf bytes.Buffer
995- runtime .GC ()
996- require .NoError (b , p .WriteTo (& buf , 0 ))
997- pBase , err := profile .ParseData (buf .Bytes ())
1024+
1025+ baseBytes := take ()
1026+ if baseBytes == nil {
1027+ return func (tb testing.TB ) []byte { return nil }
1028+ }
1029+ pBase , err := profile .ParseData (baseBytes )
9981030 require .NoError (b , err )
9991031
1000- return func (b testing.TB ) {
1001- runtime .GC ()
1002- var buf bytes.Buffer
1003- require .NoError (b , p .WriteTo (& buf , 0 ))
1004- pNew , err := profile .ParseData (buf .Bytes ())
1032+ return func (b testing.TB ) []byte {
1033+ pNew , err := profile .ParseData (take ())
10051034 require .NoError (b , err )
10061035 pBase .Scale (- 1 )
10071036 pMerged , err := profile .Merge ([]* profile.Profile {pBase , pNew })
10081037 require .NoError (b , err )
10091038 pMerged .TimeNanos = pNew .TimeNanos
10101039 pMerged .DurationNanos = pNew .TimeNanos - pBase .TimeNanos
10111040
1012- buf = bytes.Buffer {}
1041+ buf : = bytes.Buffer {}
10131042 require .NoError (b , pMerged .Write (& buf ))
1014- require . NoError ( b , os . WriteFile ( out , buf .Bytes (), 0644 ) )
1043+ return buf .Bytes ()
10151044 }
10161045}
10171046
1018- // If -test.benchmem is passed, also write a base alloc profile when the
1019- // setup is done. This can be used via `pprof -base` to show only the
1020- // allocs during run (excluding the setup).
1047+ // If -test.<something> is passed for the flag corresponding to the given
1048+ // profile, also write a base profile when the setup is done. This can be used
1049+ // via `pprof -base` to show only the samples from during run (excluding the
1050+ // setup).
10211051//
1022- // The file name for the base profile will be derived from -test.memprofile , and
1052+ // The file name for the base profile will be derived from -test.<flag> , and
10231053// will contain it as a prefix (mod the file extension).
1024- func benchmemFile (b testing.TB ) string {
1054+ func testProfileFile (b testing.TB , flagWithoutTestPrefix string ) string {
10251055 b .Helper ()
1026- var benchMemFile string
1056+ var flagFile string
10271057 var outputDir string
1028- require .NoError (b , sniffarg .DoEnv ("test.memprofile" , & benchMemFile ))
1058+ require .NoError (b , sniffarg .DoEnv ("test." + flagWithoutTestPrefix , & flagFile ))
10291059 require .NoError (b , sniffarg .DoEnv ("test.outputdir" , & outputDir ))
10301060
1031- if benchMemFile == "" {
1061+ if flagFile == "" {
10321062 return ""
10331063 }
10341064
10351065 saniRE := regexp .MustCompile (`\W+` )
10361066 saniName := saniRE .ReplaceAllString (strings .TrimPrefix (b .Name (), "Benchmark" ), "_" )
1037- dest := strings .Replace (benchMemFile , "." , "_" + saniName + "." , 1 )
1067+ dest := strings .Replace (flagFile , "." , "_" + saniName + "." , 1 )
10381068 if outputDir != "" {
10391069 dest = filepath .Join (outputDir , dest )
10401070 }
0 commit comments