Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.24.9
require (
github.com/chzyer/readline v1.5.1
github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b
golang.org/x/mod v0.31.0
)

require golang.org/x/sys v0.32.0 // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b h1:ogbOPx86mIhFy764gGkqnkFC8m5PJA7sPzlk9ppLVQA=
github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
50 changes: 49 additions & 1 deletion internal/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import (
"fmt"
"io"
"net/url"
"os"
"path/filepath"
"regexp"
"runtime"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -84,6 +86,28 @@ type Options struct {
IntelSyntax bool // Whether or not to print assembly in Intel syntax.
}

func (o *Options) sourcePaths() []string {
sourcePaths := filepath.SplitList(o.SourcePath)
if len(sourcePaths) == 0 {
// Search for source files in the current directory by default.
cwd, err := os.Getwd()
if err != nil {
cwd = "."
}
sourcePaths = []string{cwd}
}

// Always search for source files in $GOROOT/src (aka standard packages)
// as a fallback.
sourcePaths = append(sourcePaths, filepath.Join(runtime.GOROOT(), "src"))

return sourcePaths
}

func (o *Options) trimPaths() []string {
return filepath.SplitList(o.TrimPath)
}

// Generate generates a report as directed by the Report.
func Generate(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
o := rpt.options
Expand Down Expand Up @@ -240,9 +264,12 @@ func (rpt *Report) newGraph(nodes graph.NodeSet) *graph.Graph {

// Clean up file paths using heuristics.
prof := rpt.prof
sourcePaths := o.sourcePaths()
trimPaths := o.trimPaths()
for _, f := range prof.Function {
f.Filename = trimPath(f.Filename, o.TrimPath, o.SourcePath)
f.Filename = sourceFilename(f.Filename, sourcePaths, trimPaths)
}

// Removes all numeric tags except for the bytes tag prior
// to making graph.
// TODO: modify to select first numeric tag if no bytes tag
Expand Down Expand Up @@ -293,6 +320,27 @@ func (rpt *Report) newGraph(nodes graph.NodeSet) *graph.Graph {
return graph.New(rpt.prof, gopt)
}

// sourceFilename returns filename path to the given path.
func sourceFilename(path string, sourcePaths, trimPaths []string) string {
f := tryOpenSourceFile(path, sourcePaths, trimPaths)
if f == nil {
return path
}
filename := f.Name()
_ = f.Close()

// Trim current directory from filename for simpler readability
wd, err := os.Getwd()
if err == nil {
if !strings.HasSuffix(wd, string(filepath.Separator)) {
wd += string(filepath.Separator)
}
filename = strings.TrimPrefix(filename, wd)
}

return filename
}

// printProto writes the incoming proto via the writer w.
// If the divide_by option has been specified, samples are scaled appropriately.
func printProto(w io.Writer, rpt *Report) error {
Expand Down
Loading