diff options
Diffstat (limited to 'src/cmd/vendor/github.com/google/pprof/internal')
19 files changed, 87 insertions, 270 deletions
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go index 491422fcda..3049545b6b 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/binutils/addr2liner_llvm.go @@ -129,6 +129,7 @@ func (d *llvmSymbolizer) readFrame() (plugin.Frame, bool) { } linenumber := 0 + columnnumber := 0 // The llvm-symbolizer outputs the <file_name>:<line_number>:<column_number>. // When it cannot identify the source code location, it outputs "??:0:0". // Older versions output just the filename and line number, so we check for @@ -137,22 +138,27 @@ func (d *llvmSymbolizer) readFrame() (plugin.Frame, bool) { fileline = "" } else { switch split := strings.Split(fileline, ":"); len(split) { - case 1: - // filename - fileline = split[0] - case 2, 3: - // filename:line , or - // filename:line:disc , or - fileline = split[0] + case 3: + // filename:line:column + if col, err := strconv.Atoi(split[2]); err == nil { + columnnumber = col + } + fallthrough + case 2: + // filename:line if line, err := strconv.Atoi(split[1]); err == nil { linenumber = line } + fallthrough + case 1: + // filename + fileline = split[0] default: // Unrecognized, ignore } } - return plugin.Frame{Func: funcname, File: fileline, Line: linenumber}, false + return plugin.Frame{Func: funcname, File: fileline, Line: linenumber, Column: columnnumber}, false } // addrInfo returns the stack frame information for a specific program diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go index c9edf10bb4..f990780d75 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go @@ -247,6 +247,8 @@ var configHelp = map[string]string{ "noinlines": helpText( "Ignore inlines.", "Attributes inlined functions to their first out-of-line caller."), + "showcolumns": helpText( + "Show column numbers at the source code line level."), } func helpText(s ...string) string { diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go index 9fcdd459b2..f7d227416e 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/config.go @@ -51,6 +51,7 @@ type config struct { TagShow string `json:"tagshow,omitempty"` TagHide string `json:"taghide,omitempty"` NoInlines bool `json:"noinlines,omitempty"` + ShowColumns bool `json:"showcolumns,omitempty"` // Output granularity Granularity string `json:"granularity,omitempty"` @@ -157,6 +158,7 @@ func init() { "sort": "sort", "granularity": "g", "noinlines": "noinlines", + "showcolumns": "showcolumns", } def := defaultConfig() diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go index 27681c540f..74ce8cb422 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go @@ -256,7 +256,7 @@ func aggregate(prof *profile.Profile, cfg config) error { default: return fmt.Errorf("unexpected granularity") } - return prof.Aggregate(inlines, function, filename, linenumber, address) + return prof.Aggregate(inlines, function, filename, linenumber, cfg.ShowColumns, address) } func reportOptions(p *profile.Profile, numLabelUnits map[string]string, cfg config) (*report.Options, error) { diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go index 584c5d85e0..95204a394f 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go @@ -492,17 +492,23 @@ mapping: func fetch(source string, duration, timeout time.Duration, ui plugin.UI, tr http.RoundTripper) (p *profile.Profile, src string, err error) { var f io.ReadCloser - if sourceURL, timeout := adjustURL(source, duration, timeout); sourceURL != "" { - ui.Print("Fetching profile over HTTP from " + sourceURL) - if duration > 0 { - ui.Print(fmt.Sprintf("Please wait... (%v)", duration)) + // First determine whether the source is a file, if not, it will be treated as a URL. + if _, openErr := os.Stat(source); openErr == nil { + if isPerfFile(source) { + f, err = convertPerfData(source, ui) + } else { + f, err = os.Open(source) } - f, err = fetchURL(sourceURL, timeout, tr) - src = sourceURL - } else if isPerfFile(source) { - f, err = convertPerfData(source, ui) } else { - f, err = os.Open(source) + sourceURL, timeout := adjustURL(source, duration, timeout) + if sourceURL != "" { + ui.Print("Fetching profile over HTTP from " + sourceURL) + if duration > 0 { + ui.Print(fmt.Sprintf("Please wait... (%v)", duration)) + } + f, err = fetchURL(sourceURL, timeout, tr) + src = sourceURL + } } if err == nil { defer f.Close() diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/flamegraph.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/flamegraph.go deleted file mode 100644 index fbeb765dbc..0000000000 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/flamegraph.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2017 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package driver - -import ( - "encoding/json" - "html/template" - "net/http" - "strings" - - "github.com/google/pprof/internal/graph" - "github.com/google/pprof/internal/measurement" - "github.com/google/pprof/internal/report" -) - -type treeNode struct { - Name string `json:"n"` - FullName string `json:"f"` - Cum int64 `json:"v"` - CumFormat string `json:"l"` - Percent string `json:"p"` - Children []*treeNode `json:"c"` -} - -// flamegraph generates a web page containing a flamegraph. -func (ui *webInterface) flamegraph(w http.ResponseWriter, req *http.Request) { - // Force the call tree so that the graph is a tree. - // Also do not trim the tree so that the flame graph contains all functions. - rpt, errList := ui.makeReport(w, req, []string{"svg"}, func(cfg *config) { - cfg.CallTree = true - cfg.Trim = false - }) - if rpt == nil { - return // error already reported - } - - // Generate dot graph. - g, config := report.GetDOT(rpt) - var nodes []*treeNode - nroots := 0 - rootValue := int64(0) - nodeArr := []string{} - nodeMap := map[*graph.Node]*treeNode{} - // Make all nodes and the map, collect the roots. - for _, n := range g.Nodes { - v := n.CumValue() - fullName := n.Info.PrintableName() - node := &treeNode{ - Name: graph.ShortenFunctionName(fullName), - FullName: fullName, - Cum: v, - CumFormat: config.FormatValue(v), - Percent: strings.TrimSpace(measurement.Percentage(v, config.Total)), - } - nodes = append(nodes, node) - if len(n.In) == 0 { - nodes[nroots], nodes[len(nodes)-1] = nodes[len(nodes)-1], nodes[nroots] - nroots++ - rootValue += v - } - nodeMap[n] = node - // Get all node names into an array. - nodeArr = append(nodeArr, n.Info.Name) - } - // Populate the child links. - for _, n := range g.Nodes { - node := nodeMap[n] - for child := range n.Out { - node.Children = append(node.Children, nodeMap[child]) - } - } - - rootNode := &treeNode{ - Name: "root", - FullName: "root", - Cum: rootValue, - CumFormat: config.FormatValue(rootValue), - Percent: strings.TrimSpace(measurement.Percentage(rootValue, config.Total)), - Children: nodes[0:nroots], - } - - // JSON marshalling flame graph - b, err := json.Marshal(rootNode) - if err != nil { - http.Error(w, "error serializing flame graph", http.StatusInternalServerError) - ui.options.UI.PrintErr(err) - return - } - - ui.render(w, req, "flamegraph", rpt, errList, config.Labels, webArgs{ - FlameGraph: template.JS(b), - Nodes: nodeArr, - }) -} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js index ff980f66de..4a2067eb68 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js @@ -558,11 +558,6 @@ function viewer(baseUrl, nodes, options) { return null; } - // convert a string to a regexp that matches that string. - function quotemeta(str) { - return str.replace(/([\\\.?+*\[\](){}|^$])/g, '\\$1'); - } - function setSampleIndexLink(si) { const elem = document.getElementById('sampletype-' + si); if (elem != null) { @@ -595,7 +590,7 @@ function viewer(baseUrl, nodes, options) { // list-based. Construct regular expression depending on mode. let re = regexpActive ? search.value - : Array.from(getSelection().keys()).map(key => quotemeta(nodes[key])).join('|'); + : Array.from(getSelection().keys()).map(key => pprofQuoteMeta(nodes[key])).join('|'); setHrefParams(elem, function (params) { if (re != '') { @@ -683,7 +678,7 @@ function viewer(baseUrl, nodes, options) { } const ids = ['topbtn', 'graphbtn', - 'flamegraph', 'flamegraph2', 'flamegraphold', + 'flamegraph', 'peek', 'list', 'disasm', 'focus', 'ignore', 'hide', 'show', 'show-from']; ids.forEach(makeSearchLinkDynamic); @@ -712,3 +707,8 @@ function viewer(baseUrl, nodes, options) { main.focus(); } } + +// convert a string to a regexp that matches exactly that string. +function pprofQuoteMeta(str) { + return '^' + str.replace(/([\\\.?+*\[\](){}|^$])/g, '\\$1') + '$'; +} diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/flamegraph.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/flamegraph.html deleted file mode 100644 index 9866755bcd..0000000000 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/flamegraph.html +++ /dev/null @@ -1,103 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>{{.Title}}</title> - {{template "css" .}} - <style type="text/css">{{template "d3flamegraphcss" .}}</style> - <style type="text/css"> - .flamegraph-content { - width: 90%; - min-width: 80%; - margin-left: 5%; - } - .flamegraph-details { - height: 1.2em; - width: 90%; - min-width: 90%; - margin-left: 5%; - padding: 15px 0 35px; - } - </style> -</head> -<body> - {{template "header" .}} - <div id="bodycontainer"> - <div id="flamegraphdetails" class="flamegraph-details"></div> - <div class="flamegraph-content"> - <div id="chart"></div> - </div> - </div> - {{template "script" .}} - <script>viewer(new URL(window.location.href), {{.Nodes}});</script> - <script>{{template "d3flamegraphscript" .}}</script> - <script> - {{- /* Deserialize as JSON instead of a JS object literal because the browser's - JSON parser can handle larger payloads than its JS parser. */ -}} - var data = JSON.parse("{{.FlameGraph}}"); - - var width = document.getElementById('chart').clientWidth; - - var flameGraph = flamegraph() - .width(width) - .cellHeight(18) - .minFrameSize(1) - .transitionDuration(750) - .inverted(true) - .sort(true) - .title('') - .tooltip(false) - .setDetailsElement(document.getElementById('flamegraphdetails')); - - // <full name> (percentage, value) - flameGraph.label((d) => d.data.f + ' (' + d.data.p + ', ' + d.data.l + ')'); - - flameGraph.setColorHue('warm'); - - select('#chart') - .datum(data) - .call(flameGraph); - - function clear() { - flameGraph.clear(); - } - - function resetZoom() { - flameGraph.resetZoom(); - } - - window.addEventListener('resize', function() { - var width = document.getElementById('chart').clientWidth; - var graphs = document.getElementsByClassName('d3-flame-graph'); - if (graphs.length > 0) { - graphs[0].setAttribute('width', width); - } - flameGraph.width(width); - flameGraph.resetZoom(); - }, true); - - var search = document.getElementById('search'); - var searchAlarm = null; - - function selectMatching() { - searchAlarm = null; - - if (search.value != '') { - flameGraph.search(search.value); - } else { - flameGraph.clear(); - } - } - - function handleSearch() { - // Delay expensive processing so a flurry of key strokes is handled once. - if (searchAlarm != null) { - clearTimeout(searchAlarm); - } - searchAlarm = setTimeout(selectMatching, 300); - } - - search.addEventListener('input', handleSearch); - </script> -</body> -</html> diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html index 42cb7960e6..e946e6b882 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html @@ -12,7 +12,6 @@ <a title="{{.Help.top}}" href="./top" id="topbtn">Top</a> <a title="{{.Help.graph}}" href="./" id="graphbtn">Graph</a> <a title="{{.Help.flamegraph}}" href="./flamegraph" id="flamegraph">Flame Graph</a> - <a title="{{.Help.flamegraphold}}" href="./flamegraphold" id="flamegraphold">Flame Graph (old)</a> <a title="{{.Help.peek}}" href="./peek" id="peek">Peek</a> <a title="{{.Help.list}}" href="./source" id="list">Source</a> <a title="{{.Help.disasm}}" href="./disasm" id="disasm">Disassemble</a> diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js index be78edd553..c8059fe6bf 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js @@ -75,8 +75,12 @@ function stackViewer(stacks, nodes) { hiliter: (n, on) => { return hilite(n, on); }, current: () => { let r = new Map(); - for (let p of pivots) { - r.set(p, true); + if (pivots.length == 1 && pivots[0] == 0) { + // Not pivoting + } else { + for (let p of pivots) { + r.set(p, true); + } } return r; }}); @@ -145,7 +149,7 @@ function stackViewer(stacks, nodes) { } // Update params to include src. - let v = stacks.Sources[src].RE; + let v = pprofQuoteMeta(stacks.Sources[src].FullName); if (param != 'f' && param != 'sf') { // old f,sf values are overwritten // Add new source to current parameter value. const old = params.get(param); @@ -174,7 +178,11 @@ function stackViewer(stacks, nodes) { function switchPivots(regexp) { // Switch URL without hitting the server. const url = new URL(document.URL); - url.searchParams.set('p', regexp); + if (regexp === '' || regexp === '^$') { + url.searchParams.delete('p'); // Not pivoting + } else { + url.searchParams.set('p', regexp); + } history.pushState('', '', url.toString()); // Makes back-button work matches = new Set(); search.value = ''; @@ -445,7 +453,7 @@ function stackViewer(stacks, nodes) { r.appendChild(t); } - r.addEventListener('click', () => { switchPivots(src.RE); }); + r.addEventListener('click', () => { switchPivots(pprofQuoteMeta(src.UniqueName)); }); r.addEventListener('mouseenter', () => { handleEnter(box, r); }); r.addEventListener('mouseleave', () => { handleLeave(box); }); r.addEventListener('contextmenu', (e) => { showActionMenu(e, box); }); diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go index 249dfe0742..6a61613344 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go @@ -22,7 +22,7 @@ import ( "github.com/google/pprof/internal/report" ) -// stackView generates the new flamegraph view. +// stackView generates the flamegraph view. func (ui *webInterface) stackView(w http.ResponseWriter, req *http.Request) { // Get all data in a report. rpt, errList := ui.makeReport(w, req, []string{"svg"}, func(cfg *config) { diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/svg.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/svg.go index 62767e726d..9cbef4d787 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/svg.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/svg.go @@ -65,7 +65,7 @@ func massageSVG(svg string) string { if loc := graphID.FindStringIndex(svg); loc != nil { svg = svg[:loc[0]] + - `<script type="text/ecmascript"><![CDATA[` + string(svgpan.JSSource) + `]]></script>` + + `<script type="text/ecmascript"><![CDATA[` + svgpan.JSSource + `]]></script>` + `<g id="viewport" transform="scale(0.5,0.5) translate(0,0)">` + svg[loc[0]:] } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go index 55973ffb9f..984936a9d6 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go @@ -19,8 +19,6 @@ import ( "fmt" "html/template" "os" - - "github.com/google/pprof/third_party/d3flamegraph" ) //go:embed html @@ -52,11 +50,7 @@ func addTemplates(templates *template.Template) { template.Must(templates.AddParseTree(name, sub.Tree)) } - // Pre-packaged third-party files. - def("d3flamegraphscript", d3flamegraph.JSSource) - def("d3flamegraphcss", d3flamegraph.CSSSource) - - // Embeded files. + // Embedded files. def("css", loadCSS("html/common.css")) def("header", loadFile("html/header.html")) def("graph", loadFile("html/graph.html")) @@ -64,7 +58,7 @@ func addTemplates(templates *template.Template) { def("top", loadFile("html/top.html")) def("sourcelisting", loadFile("html/source.html")) def("plaintext", loadFile("html/plaintext.html")) - def("flamegraph", loadFile("html/flamegraph.html")) + // TODO: Rename "stacks" to "flamegraph" to seal moving off d3 flamegraph. def("stacks", loadFile("html/stacks.html")) def("stacks_css", loadCSS("html/stacks.css")) def("stacks_js", loadJS("html/stacks.js")) diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go index 41b30021f5..476e1d2cdf 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go @@ -112,7 +112,6 @@ func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, d ui.help["details"] = "Show information about the profile and this view" ui.help["graph"] = "Display profile as a directed graph" ui.help["flamegraph"] = "Display profile as a flame graph" - ui.help["flamegraphold"] = "Display profile as a flame graph (old version; slated for removal)" ui.help["reset"] = "Show the entire profile" ui.help["save_config"] = "Save current settings" @@ -130,9 +129,9 @@ func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options, d "/disasm": http.HandlerFunc(ui.disasm), "/source": http.HandlerFunc(ui.source), "/peek": http.HandlerFunc(ui.peek), - "/flamegraphold": http.HandlerFunc(ui.flamegraph), "/flamegraph": http.HandlerFunc(ui.stackView), - "/flamegraph2": http.HandlerFunc(ui.stackView), // Support older URL + "/flamegraph2": redirectWithQuery("flamegraph", http.StatusMovedPermanently), // Keep legacy URL working. + "/flamegraphold": redirectWithQuery("flamegraph", http.StatusMovedPermanently), // Keep legacy URL working. "/saveconfig": http.HandlerFunc(ui.saveConfig), "/deleteconfig": http.HandlerFunc(ui.deleteConfig), "/download": http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { @@ -209,15 +208,20 @@ func defaultWebServer(args *plugin.HTTPServerArgs) error { // https://github.com/google/pprof/pull/348 mux := http.NewServeMux() mux.Handle("/ui/", http.StripPrefix("/ui", handler)) - mux.Handle("/", redirectWithQuery("/ui")) + mux.Handle("/", redirectWithQuery("/ui", http.StatusTemporaryRedirect)) s := &http.Server{Handler: mux} return s.Serve(ln) } -func redirectWithQuery(path string) http.HandlerFunc { +// redirectWithQuery responds with a given redirect code, preserving query +// parameters in the redirect URL. It does not convert relative paths to +// absolute paths like http.Redirect does, so that HTTPServerArgs.Handlers can +// generate relative redirects that work with the external prefixing. +func redirectWithQuery(path string, code int) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { pathWithQuery := &gourl.URL{Path: path, RawQuery: r.URL.RawQuery} - http.Redirect(w, r, pathWithQuery.String(), http.StatusTemporaryRedirect) + w.Header().Set("Location", pathWithQuery.String()) + w.WriteHeader(code) } } diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go index b64ef27991..5ad10a2ae0 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go @@ -154,6 +154,7 @@ type NodeInfo struct { Address uint64 File string StartLine, Lineno int + Columnno int Objfile string } @@ -174,8 +175,12 @@ func (i *NodeInfo) NameComponents() []string { switch { case i.Lineno != 0: + s := fmt.Sprintf("%s:%d", i.File, i.Lineno) + if i.Columnno != 0 { + s += fmt.Sprintf(":%d", i.Columnno) + } // User requested line numbers, provide what we have. - name = append(name, fmt.Sprintf("%s:%d", i.File, i.Lineno)) + name = append(name, s) case i.File != "": // User requested file name, provide it. name = append(name, i.File) @@ -239,6 +244,7 @@ func (nm NodeMap) FindOrInsertNode(info NodeInfo, kept NodeSet) *Node { // Find a node that represents the whole function. info.Address = 0 info.Lineno = 0 + info.Columnno = 0 n.Function = nm.FindOrInsertNode(info, nil) return n } @@ -592,9 +598,10 @@ func nodeInfo(l *profile.Location, line profile.Line, objfile string, o *Options return &NodeInfo{Address: l.Address, Objfile: objfile} } ni := &NodeInfo{ - Address: l.Address, - Lineno: int(line.Line), - Name: line.Function.Name, + Address: l.Address, + Lineno: int(line.Line), + Columnno: int(line.Column), + Name: line.Function.Name, } if fname := line.Function.Filename; fname != "" { ni.File = filepath.Clean(fname) diff --git a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go index 98eb1dd817..c934551036 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/plugin/plugin.go @@ -157,11 +157,12 @@ type ObjFile interface { Close() error } -// A Frame describes a single line in a source file. +// A Frame describes a location in a single line in a source file. type Frame struct { - Func string // name of function - File string // source file name - Line int // line in file + Func string // name of function + File string // source file name + Line int // line in file + Column int // column in line (if available) } // A Sym describes a single symbol in an object file. diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go index f73e49a176..96b80039e6 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/report/report.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/report/report.go @@ -293,7 +293,7 @@ func (rpt *Report) newGraph(nodes graph.NodeSet) *graph.Graph { return graph.New(rpt.prof, gopt) } -// printProto writes the incoming proto via thw writer w. +// 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 { p, o := rpt.prof, rpt.options @@ -339,6 +339,7 @@ func printTopProto(w io.Writer, rpt *Report) error { Line: []profile.Line{ { Line: int64(n.Info.Lineno), + Column: int64(n.Info.Columnno), Function: f, }, }, diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/stacks.go b/src/cmd/vendor/github.com/google/pprof/internal/report/stacks.go index 7db51bc01c..aa3bf80f2d 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/report/stacks.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/report/stacks.go @@ -18,7 +18,6 @@ import ( "crypto/sha256" "encoding/binary" "fmt" - "regexp" "github.com/google/pprof/internal/measurement" "github.com/google/pprof/profile" @@ -54,9 +53,6 @@ type StackSource struct { // Guaranteed to be non-empty. Display []string - // Regular expression (anchored) that matches exactly FullName. - RE string - // Places holds the list of stack slots where this source occurs. // In particular, if [a,b] is an element in Places, // StackSet.Stacks[a].Sources[b] points to this source. @@ -135,7 +131,6 @@ func (s *StackSet) makeInitialStacks(rpt *Report) { unknownIndex++ } x.Inlined = inlined - x.RE = "^" + regexp.QuoteMeta(x.UniqueName) + "$" x.Display = shortNameList(x.FullName) s.Sources = append(s.Sources, x) srcs[k] = len(s.Sources) - 1 diff --git a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go index c3f6cc6281..5ca71ab8be 100644 --- a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go +++ b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go @@ -181,6 +181,7 @@ func doLocalSymbolize(prof *profile.Profile, fast, force bool, obj plugin.ObjToo l.Line[i] = profile.Line{ Function: f, Line: int64(frame.Line), + Column: int64(frame.Column), } } |
