Skip to content
12 changes: 8 additions & 4 deletions cmd/grf/cmds/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ var (

// verbose is whether to log verbose info, like debug logs.
verbose bool

// useMarkStub is whether to use mark stub for object reference analysis.
useMarkStub bool
)

// New returns an initialized command tree.
Expand Down Expand Up @@ -75,6 +78,7 @@ You'll have to wait for goref until it outputs 'successfully output to ...', or
}
attachCommand.Flags().IntVar(&maxRefDepth, "max-depth", 0, "max reference depth shown by pprof")
attachCommand.Flags().StringVarP(&outFile, "out", "o", "grf.out", "output file name")
attachCommand.Flags().BoolVar(&useMarkStub, "usemarkstub", false, "use mark stub for partial object reference analysis")
rootCommand.AddCommand(attachCommand)

coreCommand := &cobra.Command{
Expand Down Expand Up @@ -130,14 +134,14 @@ func attachCmd(_ *cobra.Command, args []string) {
if len(args) > 1 {
exeFile = args[1]
}
os.Exit(execute(pid, exeFile, "", outFile, conf))
os.Exit(execute(pid, exeFile, "", outFile, useMarkStub, conf))
}

func coreCmd(_ *cobra.Command, args []string) {
os.Exit(execute(0, args[0], args[1], outFile, conf))
os.Exit(execute(0, args[0], args[1], outFile, useMarkStub, conf))
}

func execute(attachPid int, exeFile, coreFile, outFile string, conf *config.Config) int {
func execute(attachPid int, exeFile, coreFile, outFile string, useMarkStub bool, conf *config.Config) int {
if verbose {
if err := logflags.Setup(verbose, "", ""); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
Expand Down Expand Up @@ -175,7 +179,7 @@ func execute(attachPid int, exeFile, coreFile, outFile string, conf *config.Conf
func() {
tg, unlock := dbg.LockTargetGroup()
defer unlock()
_, err = myproc.ObjectReference(tg.Selected, outFile)
_, err = myproc.ObjectReference(tg.Selected, outFile, useMarkStub)
}()
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
Expand Down
27 changes: 27 additions & 0 deletions cmd/grf/cmds/self_attach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cmds

import (
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
)

// AttachSelf create new grf process to attach to caller's pid
func AttachSelf(filename string) error {
// check grf first
binName := "grf"
if runtime.GOOS == "windows" {
binName = "grf.exe"
}

grfPath, err := exec.LookPath(binName)
if err != nil {
return fmt.Errorf("grf not found in PATH: %v", err)
}

// execute grf
cmd := exec.Command(grfPath, "attach", strconv.Itoa(os.Getpid()), "-o", filename)
return cmd.Run()
}
14 changes: 13 additions & 1 deletion pkg/proc/heap.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ type HeapScope struct {
greenTeaGCEnabled bool
spanInlineMarkBitsSize int64
inlineMarkSpanPages map[Address]struct{}
// stub address
markStubAddr Address // address for pkg/stub.markStub
}

func (s *HeapScope) readHeap() error {
Expand Down Expand Up @@ -422,7 +424,7 @@ func (s *HeapScope) readBitmapFunc(heapArena *region) func(heapArena *region, mi
}
}

// base must be the base address of an object in then span
// base must be the base address of an object in the span
func (s *HeapScope) copyGCMask(sp *spanInfo, base Address) Address {
if !s.enableAllocHeader {
return base
Expand Down Expand Up @@ -866,3 +868,13 @@ func (s *HeapScope) rtConstant(name string) int64 {
}
return 0
}

func (s *HeapScope) readMarkStubAddr() error {
tmp, err := s.scope.EvalExpression("stub.markStub", loadSingleValue)
if err != nil {
return err
}
markStub := toRegion(tmp, s.bi)
s.markStubAddr = markStub.a
return nil
}
Loading