Source File
profile.go
Belonging Package
github.com/google/pprof/profile
package profile
import (
)
type Profile struct {
SampleType []*ValueType
DefaultSampleType string
Sample []*Sample
Mapping []*Mapping
Location []*Location
Function []*Function
Comments []string
DropFrames string
KeepFrames string
TimeNanos int64
DurationNanos int64
PeriodType *ValueType
Period int64
type label struct {
func ( []byte) (*Profile, error) {
var *Profile
var error
if len() >= 2 && [0] == 0x1f && [1] == 0x8b {
, := gzip.NewReader(bytes.NewBuffer())
if == nil {
, = ioutil.ReadAll()
}
if != nil {
return nil, fmt.Errorf("decompressing profile: %v", )
}
}
if , = ParseUncompressed(); != nil && != errNoData && != errConcatProfile {
, = parseLegacy()
}
if != nil {
return nil, fmt.Errorf("parsing profile: %v", )
}
if := .CheckValid(); != nil {
return nil, fmt.Errorf("malformed profile: %v", )
}
return , nil
}
var errUnrecognized = fmt.Errorf("unrecognized profile format")
var errMalformed = fmt.Errorf("malformed profile format")
var errNoData = fmt.Errorf("empty input file")
var errConcatProfile = fmt.Errorf("concatenated profiles detected")
func ( []byte) (*Profile, error) {
:= []func([]byte) (*Profile, error){
parseCPU,
parseHeap,
parseGoCount, // goroutine, threadcreate
parseThread,
parseContention,
parseJavaProfile,
}
for , := range {
, := ()
if == nil {
.addLegacyFrameInfo()
return , nil
}
if != errUnrecognized {
return nil,
}
}
return nil, errUnrecognized
}
func (, *Mapping) bool {
if .File != "" && .File != "" {
if .File != .File {
return false
}
}
if .BuildID != "" && .BuildID != "" {
if .BuildID != .BuildID {
return false
}
}
if .Limit != .Start {
return false
}
if .Offset != 0 && .Offset != 0 {
:= .Offset + (.Limit - .Start)
if != .Offset {
return false
}
}
return true
}
func ( *Profile) (, *Mapping) {
for , := range .Location {
if .Mapping == {
.Mapping =
}
}
}
func ( *Profile) []byte {
.encodeMu.Lock()
.preEncode()
:= marshal()
.encodeMu.Unlock()
return
}
:= len(.SampleType)
if == 0 && len(.Sample) != 0 {
return fmt.Errorf("missing sample type information")
}
for , := range .Sample {
if == nil {
return fmt.Errorf("profile has nil sample")
}
if len(.Value) != {
return fmt.Errorf("mismatch: sample has %d values vs. %d types", len(.Value), len(.SampleType))
}
for , := range .Location {
if == nil {
return fmt.Errorf("sample has nil location")
}
}
}
:= make(map[uint64]*Mapping, len(.Mapping))
for , := range .Mapping {
if == nil {
return fmt.Errorf("profile has nil mapping")
}
if .ID == 0 {
return fmt.Errorf("found mapping with reserved ID=0")
}
if [.ID] != nil {
return fmt.Errorf("multiple mappings with same id: %d", .ID)
}
[.ID] =
}
:= make(map[uint64]*Function, len(.Function))
for , := range .Function {
if == nil {
return fmt.Errorf("profile has nil function")
}
if .ID == 0 {
return fmt.Errorf("found function with reserved ID=0")
}
if [.ID] != nil {
return fmt.Errorf("multiple functions with same id: %d", .ID)
}
[.ID] =
}
:= make(map[uint64]*Location, len(.Location))
for , := range .Location {
if == nil {
return fmt.Errorf("profile has nil location")
}
if .ID == 0 {
return fmt.Errorf("found location with reserved id=0")
}
if [.ID] != nil {
return fmt.Errorf("multiple locations with same id: %d", .ID)
}
[.ID] =
if := .Mapping; != nil {
if .ID == 0 || [.ID] != {
return fmt.Errorf("inconsistent mapping %p: %d", , .ID)
}
}
for , := range .Line {
:= .Function
if == nil {
return fmt.Errorf("location id: %d has a line with nil function", .ID)
}
if .ID == 0 || [.ID] != {
return fmt.Errorf("inconsistent function %p: %d", , .ID)
}
}
}
return nil
}
func ( *Profile) (, , , , bool) error {
for , := range .Mapping {
.HasInlineFrames = .HasInlineFrames &&
.HasFunctions = .HasFunctions &&
.HasFilenames = .HasFilenames &&
.HasLineNumbers = .HasLineNumbers &&
}
if ! || ! {
for , := range .Function {
if ! {
.Name = ""
.SystemName = ""
}
if ! {
.Filename = ""
}
}
}
for := range {
:= []
if == "" {
switch {
case "alignment", "request":
[] = "bytes"
default:
[] =
}
}
}
func ( *Profile) () string {
:= make([]string, 0, len(.Comments)+len(.Sample)+len(.Mapping)+len(.Location))
for , := range .Comments {
= append(, "Comment: "+)
}
if := .PeriodType; != nil {
= append(, fmt.Sprintf("PeriodType: %s %s", .Type, .Unit))
}
= append(, fmt.Sprintf("Period: %d", .Period))
if .TimeNanos != 0 {
= append(, fmt.Sprintf("Time: %v", time.Unix(0, .TimeNanos)))
}
if .DurationNanos != 0 {
= append(, fmt.Sprintf("Duration: %.4v", time.Duration(.DurationNanos)))
}
= append(, "Samples:")
var string
for , := range .SampleType {
:= ""
if .Type == .DefaultSampleType {
= "[dflt]"
}
= + fmt.Sprintf("%s/%s%s ", .Type, .Unit, )
}
= append(, strings.TrimSpace())
for , := range .Sample {
= append(, .string())
}
= append(, "Locations")
for , := range .Location {
= append(, .string())
}
= append(, "Mappings")
for , := range .Mapping {
= append(, .string())
}
return strings.Join(, "\n") + "\n"
}
func ( *Mapping) () string {
:= ""
if .HasFunctions {
= + "[FN]"
}
if .HasFilenames {
= + "[FL]"
}
if .HasLineNumbers {
= + "[LN]"
}
if .HasInlineFrames {
= + "[IN]"
}
return fmt.Sprintf("%d: %#x/%#x/%#x %s %s %s",
.ID,
.Start, .Limit, .Offset,
.File,
.BuildID,
)
}
func ( *Location) () string {
:= []string{}
:= fmt.Sprintf("%6d: %#x ", .ID, .Address)
if := .Mapping; != nil {
= + fmt.Sprintf("M=%d ", .ID)
}
if .IsFolded {
= + "[F] "
}
if len(.Line) == 0 {
= append(, )
}
for := range .Line {
:= "??"
if := .Line[].Function; != nil {
= fmt.Sprintf("%s %s:%d s=%d",
.Name,
.Filename,
.Line[].Line,
.StartLine)
if .Name != .SystemName {
= + "(" + .SystemName + ")"
}
}
func ( *Sample) () string {
:= []string{}
var string
for , := range .Value {
= fmt.Sprintf("%s %10d", , )
}
= + ": "
for , := range .Location {
= + fmt.Sprintf("%d ", .ID)
}
= append(, )
const = " "
if len(.Label) > 0 {
= append(, +labelsToString(.Label))
}
if len(.NumLabel) > 0 {
= append(, +numLabelsToString(.NumLabel, .NumUnit))
}
return strings.Join(, "\n")
}
func ( map[string][]int64, map[string][]string) string {
:= []string{}
for , := range {
:= []
var string
if len() == len() {
:= make([]string, len())
for , := range {
[] = fmt.Sprintf("%d %s", , [])
}
= fmt.Sprintf("%s:%v", , )
} else {
= fmt.Sprintf("%s:%v", , )
}
= append(, )
}
sort.Strings()
return strings.Join(, " ")
}
func ( *Profile) ( float64) {
if == 1 {
return
}
:= make([]float64, len(.SampleType))
for := range .SampleType {
[] =
}
.ScaleN()
}
func ( *Profile) ( []float64) error {
if len(.SampleType) != len() {
return fmt.Errorf("mismatched scale ratios, got %d, want %d", len(), len(.SampleType))
}
:= true
for , := range {
if != 1 {
= false
break
}
}
if {
return nil
}
for , := range .Sample {
for , := range .Value {
if [] != 1 {
.Value[] = int64(float64() * [])
}
}
}
return nil
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |