Support showing pprof lines from the pprof Line object (take 2) (#430)

The previous behavior was to use the StartLine of a function as the line number to show in speedscope. However, the Line object has more precise line information, and we should only fallback to StartLine if we don't have this more detailed information.

Looking at the [documentation for the pprof proto](https://github.com/google/pprof/tree/main/proto#general-structure-of-a-profile), this is more how it intends to interpret line information:

> location: A unique place in the program, commonly mapped to a single instruction address. It has a unique nonzero id, to be referenced from the samples. It contains source information in the form of lines, and a mapping id that points to a binary.
> function: A program function as defined in the program source. It has a unique nonzero id, referenced from the location lines. It contains a human-readable name for the function (eg a C++ demangled name), a system name (eg a C++ mangled name), the name of the corresponding source file, and other function attributes.

Here is a sample profile that had line-level info on the Line object of the profile:

Before:

<img width="449" alt="Screen Shot 2022-11-03 at 11 17 11 AM" src="https://user-images.githubusercontent.com/618615/199760730-712daa70-6cfb-4e90-b037-b571809c26d9.png">

After:

<img width="449" alt="Screen Shot 2022-11-03 at 11 17 22 AM" src="https://user-images.githubusercontent.com/618615/199760777-1c0d5581-7b29-42b7-b642-6035f7d25405.png">
This commit is contained in:
Jamie Wong
2023-06-21 15:25:16 -07:00
committed by GitHub
parent 741fdeb427
commit 9cdceede15
2 changed files with 32 additions and 26 deletions

View File

@@ -7,7 +7,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.main:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 198,
"name": "runtime.main",
"selfWeight": 0,
"totalWeight": 1360000000,
@@ -16,7 +16,7 @@ Object {
"col": undefined,
"file": "/Users/jlfwong/code/speedscope/sample/programs/go/simple.go",
"key": "main.main:/Users/jlfwong/code/speedscope/sample/programs/go/simple.go:0",
"line": 0,
"line": 49,
"name": "main.main",
"selfWeight": 0,
"totalWeight": 1360000000,
@@ -25,7 +25,7 @@ Object {
"col": undefined,
"file": "/Users/jlfwong/code/speedscope/sample/programs/go/simple.go",
"key": "main.delta:/Users/jlfwong/code/speedscope/sample/programs/go/simple.go:0",
"line": 0,
"line": 28,
"name": "main.delta",
"selfWeight": 220000000,
"totalWeight": 580000000,
@@ -34,7 +34,7 @@ Object {
"col": undefined,
"file": "/Users/jlfwong/code/speedscope/sample/programs/go/simple.go",
"key": "main.beta:/Users/jlfwong/code/speedscope/sample/programs/go/simple.go:0",
"line": 0,
"line": 18,
"name": "main.beta",
"selfWeight": 390000000,
"totalWeight": 390000000,
@@ -43,7 +43,7 @@ Object {
"col": undefined,
"file": "/Users/jlfwong/code/speedscope/sample/programs/go/simple.go",
"key": "main.alpha:/Users/jlfwong/code/speedscope/sample/programs/go/simple.go:0",
"line": 0,
"line": 11,
"name": "main.alpha",
"selfWeight": 480000000,
"totalWeight": 480000000,
@@ -52,7 +52,7 @@ Object {
"col": undefined,
"file": "/Users/jlfwong/code/speedscope/sample/programs/go/simple.go",
"key": "main.gamma:/Users/jlfwong/code/speedscope/sample/programs/go/simple.go:0",
"line": 0,
"line": 34,
"name": "main.gamma",
"selfWeight": 270000000,
"totalWeight": 270000000,
@@ -61,7 +61,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/asm_amd64.s",
"key": "runtime.morestack:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/asm_amd64.s:0",
"line": 0,
"line": 480,
"name": "runtime.morestack",
"selfWeight": 0,
"totalWeight": 110000000,
@@ -70,7 +70,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/stack.go",
"key": "runtime.newstack:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/stack.go:0",
"line": 0,
"line": 957,
"name": "runtime.newstack",
"selfWeight": 0,
"totalWeight": 110000000,
@@ -79,7 +79,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/duff_amd64.s",
"key": "runtime.duffcopy:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/duff_amd64.s:0",
"line": 0,
"line": 412,
"name": "runtime.duffcopy",
"selfWeight": 110000000,
"totalWeight": 110000000,
@@ -88,7 +88,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/time.go",
"key": "runtime.timerproc:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/time.go:0",
"line": 0,
"line": 247,
"name": "runtime.timerproc",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -97,7 +97,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/time.go",
"key": "runtime.goroutineReady:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/time.go:0",
"line": 0,
"line": 125,
"name": "runtime.goroutineReady",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -106,7 +106,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.goready:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 301,
"name": "runtime.goready",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -115,7 +115,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/asm_amd64.s",
"key": "runtime.systemstack:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/asm_amd64.s:0",
"line": 0,
"line": 409,
"name": "runtime.systemstack",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -124,7 +124,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.goready.func1:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 302,
"name": "runtime.goready.func1",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -133,7 +133,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.ready:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 608,
"name": "runtime.ready",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -142,7 +142,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.wakep:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 2083,
"name": "runtime.wakep",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -151,7 +151,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.startm:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 2017,
"name": "runtime.startm",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -160,7 +160,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/lock_sema.go",
"key": "runtime.notewakeup:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/lock_sema.go:0",
"line": 0,
"line": 147,
"name": "runtime.notewakeup",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -169,7 +169,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/os_darwin.go",
"key": "runtime.semawakeup:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/os_darwin.go:0",
"line": 0,
"line": 36,
"name": "runtime.semawakeup",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -178,7 +178,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/os_darwin.go",
"key": "runtime.mach_semrelease:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/os_darwin.go:0",
"line": 0,
"line": 465,
"name": "runtime.mach_semrelease",
"selfWeight": 0,
"totalWeight": 10000000,
@@ -187,7 +187,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/sys_darwin_amd64.s",
"key": "runtime.mach_semaphore_signal:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/sys_darwin_amd64.s:0",
"line": 0,
"line": 558,
"name": "runtime.mach_semaphore_signal",
"selfWeight": 10000000,
"totalWeight": 10000000,
@@ -196,7 +196,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.mstart:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 1193,
"name": "runtime.mstart",
"selfWeight": 0,
"totalWeight": 20000000,
@@ -205,7 +205,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.mstart1:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 1227,
"name": "runtime.mstart1",
"selfWeight": 0,
"totalWeight": 20000000,
@@ -214,7 +214,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go",
"key": "runtime.sysmon:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/proc.go:0",
"line": 0,
"line": 4221,
"name": "runtime.sysmon",
"selfWeight": 0,
"totalWeight": 20000000,
@@ -223,7 +223,7 @@ Object {
"col": undefined,
"file": "/usr/local/Cellar/go/1.10.1/libexec/src/runtime/sys_darwin_amd64.s",
"key": "runtime.usleep:/usr/local/Cellar/go/1.10.1/libexec/src/runtime/sys_darwin_amd64.s:0",
"line": 0,
"line": 418,
"name": "runtime.usleep",
"selfWeight": 20000000,
"totalWeight": 20000000,

View File

@@ -2,6 +2,7 @@ import {perftools} from './profile.proto.js'
import {FrameInfo, StackListProfileBuilder, Profile} from '../lib/profile'
import {lastOf} from '../lib/utils'
import {TimeFormatter, ByteFormatter} from '../lib/value-formatters'
import Long from 'long'
interface SampleType {
type: string
@@ -100,7 +101,12 @@ export function importAsPprofProfile(rawProfile: ArrayBuffer): Profile | null {
if (lastLine == null) return null
if (lastLine.functionId) {
return frameInfoByFunctionID.get(i32(lastLine.functionId)) || null
let funcFrame = frameInfoByFunctionID.get(i32(lastLine.functionId))
const line = lastLine.line instanceof Long ? lastLine.line.toNumber() : lastLine.line
if (line && line > 0 && funcFrame != null) {
funcFrame.line = line
}
return funcFrame || null
} else {
return null
}