Skip to content

net/http/pprof: malformed delta profiles caused by CL 483137 #64566

@prattmic

Description

@prattmic

As of https://go.dev/cl/483137, internal/profile.(*Profile).postDecode returns early if the profile is "empty" (i.e., contains no samples).

The runtime can generate profiles with no samples. e.g., a mutex profile when there hasn't been any sampled contention.

Such profiles are still valid, despite containing no samples. e.g., they still include the sample types and mapping. As a result of this CL, the parsed Profile type of such a profile does not have any of its strings extracted from the string table. If such a profile it rewritten via Profile.Write, it will be missing string values.

e.g.,

Good (before):

{       # (perftools.profiles.Profile) size=1.1K
  sample_type: {        # (perftools.profiles.ValueType) size=4B
    type: 1
    unit: 2
  }     # sample_type[0]
  sample_type: {        # (perftools.profiles.ValueType) size=4B
    type: 3
    unit: 4
  }     # sample_type[1]
  mapping: {    # (perftools.profiles.Mapping) size=22B
    id      : 0x0000000000000001
    memory_start     : 0x00005615a44b0000       # [if nanoseconds]: 1 day 2 hours
    memory_limit     : 0x00005615a5087000       # [if nanoseconds]: 1 day 2 hours
    filename: 5
    build_id: 6
  }     # mapping[0]
  mapping: {    # (perftools.profiles.Mapping) size=22B
    id      : 0x0000000000000002
    memory_start     : 0x00007f2d65ae3000       # [if nanoseconds]: 1 day 14 hours
    memory_limit     : 0x00007f2d65ae6000       # [if nanoseconds]: 1 day 14 hours
    filename: 7
    build_id: 8
  }     # mapping[1]
... (more mappings)
  string_table       : [ "", "contentions", "count", "delay", "nanoseconds", ... mapping strings ... ]
  time_nanos : 1701802090774144022      # 1.48Ei; 0x179e03fc2a9c2416; [as nanoseconds]: 2023-12-05 13:48:10.774144022 -0500
  period_type: {        # (perftools.profiles.ValueType) size=4B
    type: 1
    unit: 2
  }     # period_type
  period     : 1
}

Bad (after):

{       # (perftools.profiles.Profile) size=338B
  sample_type: {        # (perftools.profiles.ValueType) size=0B
  }     # sample_type[0]
  sample_type: {        # (perftools.profiles.ValueType) size=0B
  }     # sample_type[1]
  mapping: {    # (perftools.profiles.Mapping) size=18B
    id      : 0x0000000000000001
    memory_start     : 0x0000564d94a0d000       # [if nanoseconds]: 1 day 2 hours
    memory_limit     : 0x0000564d955e4000       # [if nanoseconds]: 1 day 2 hours
  }     # mapping[0]
  mapping: {    # (perftools.profiles.Mapping) size=18B
    id      : 0x0000000000000002
    memory_start     : 0x00007ff6c92be000       # [if nanoseconds]: 1 day 15 hours
    memory_limit     : 0x00007ff6c92c1000       # [if nanoseconds]: 1 day 15 hours
  }     # mapping[1]
... (more mappings)
  string_table       : [ "" ]
  time_nanos : 1701800704276216955      # 1.48Ei; 0x179e02b958e4bc7b; [as nanoseconds]: 2023-12-05 13:25:04.276216955 -0500
  period     : 1
}

The only users of internal/profile.(*Profile).Parse are PGO and net/http/pprof's serveDeltaProfile.

PGO isn't very interesting with an empty profile, but empty profiles are still interesting when collecting delta profiles. pprof chokes when trying to parse one of these malformed profiles:

$ go tool pprof /tmp/p0929574757
problem fetching source profiles: profiles have empty common sample type list

I will send a fix for this.

cc @mvdan @cherrymui @golang/runtime

Metadata

Metadata

Assignees

Labels

FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.release-blocker

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions