Skip to content

Mesure profiles that contain no callstack samples using heuristic - #3698

Draft
maciejburda wants to merge 1 commit into
developfrom
maciej.burda/perfetto-empty-profile-probe
Draft

Mesure profiles that contain no callstack samples using heuristic#3698
maciejburda wants to merge 1 commit into
developfrom
maciej.burda/perfetto-empty-profile-probe

Conversation

@maciejburda

@maciejburda maciejburda commented Aug 6, 2026

Copy link
Copy Markdown
Member

What does this PR do?

Measures how often a captured profile contains no callstack samples.

PerfSampleProbe checks whether a trace holds any TracePacket.perf_sample. ProfilingDataWriter reports the answer as perf_sample_verdict on the profiling write metric, together with the trace size, using bytes it has already read — no extra I/O.

Nothing is dropped and nothing else changes. The verdict is reported on the path where the profile is actually uploaded, so the SDK's count of empty captures covers the same population as the backend's own empty-profile count. If the two agree, the walk is validated, and file_size on the same row gives the largest empty profile seen in the field.

Dropping them comes later, once that comparison holds — the same observe-then-enforce order the clock-drift gate used in this file (f78e8a0aa, enforcement in b37401a8b).

Temporary: one file to delete once the platform stops producing these.

Motivation

Some captures run the profiler at full cadence for the whole window and produce nothing:

empty capture healthy capture
Size 1.19 MiB 2.43 MiB
Packets 45 882 51 319
Packets/sec 799 801
perf_sample 0 51 304

Every packet in the empty one is a 19-byte envelope with no sample inside, and the symbol table is filled in for samples that never arrived. Nothing about its size or cadence looks wrong, so it uploads as a normal profile.

The empty capture is Perfetto v54 / Android 17, the healthy one v50.1 / Android 16, so this looks like a platform regression rather than something the SDK is doing.

Additional Notes

Is field 66 safe to rely on?

The number is. Protobuf field numbers are the wire format and "should never be reused", and Perfetto honours that in trace_packet.proto by retiring deleted fields rather than recycling them (reserved 55;, reserved 80, 81;, reserved 106;).

What is not promised is that samples keep arriving in field 66 — it sits under == UNSTABLE / CONTEXT-SPECIFIC FIELDS == in that same file. Measuring first is what turns that from a risk into a check: if the SDK count and the backend count disagree, the premise is wrong and nothing was lost finding out.

Compression. Fields 50 and 133 report COMPRESSED — the samples may be inside a block this doesn't inflate, so that is not an empty profile.

Validation. Two real captures are checked in (~970 KB of test resources). Their sample counts, 0 and 51 304, come from Perfetto's own trace_processor rather than from this code.

Unrelated: 59 tests in ProfilingFeatureTest and ProfilingTest already fail on develop under JDK 21.

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)

@maciejburda
maciejburda requested review from a team as code owners August 6, 2026 13:35
@codecov-commenter

codecov-commenter commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.84536% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.45%. Comparing base (f1be7ec) to head (d2a9f6b).

Files with missing lines Patch % Lines
...oid/profiling/internal/perfetto/PerfSampleProbe.kt 91.38% 1 Missing and 4 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3698      +/-   ##
===========================================
+ Coverage    73.41%   73.45%   +0.04%     
===========================================
  Files          999     1000       +1     
  Lines        36565    36642      +77     
  Branches      6181     6202      +21     
===========================================
+ Hits         26842    26912      +70     
+ Misses        7998     7995       -3     
- Partials      1725     1735      +10     
Files with missing lines Coverage Δ
.../android/profiling/internal/ProfilingDataWriter.kt 89.86% <100.00%> (+1.03%) ⬆️
...oid/profiling/internal/perfetto/PerfSampleProbe.kt 91.38% <91.38%> (ø)

... and 34 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ambushwork

Copy link
Copy Markdown
Member

whether a captured Perfetto trace contains any TracePacket.perf_sample (field 66)

Overall question what is this come from?

if this is not a specification from Perfetto format but a random difference which can be changed during the Perfetto iteration, then we are sitting on a brittle workaround.

@maciejburda

Copy link
Copy Markdown
Member Author

That's a good point! Hope is that we can remove this fix once we observe ProfilingManagerAPI fix fully roll out.

@ambushwork

Copy link
Copy Markdown
Member

That's a good point! Hope is that we can remove this fix once we observe ProfilingManagerAPI fix fully roll out.

@maciejburda I need to confirm with the Perfetto team about it before merging since it doesn't come from a valid source, the risk is that it can also reject the non-empty profiles if this can vary from profiles.

@maciejburda
maciejburda marked this pull request as draft August 6, 2026 14:42
@maciejburda

maciejburda commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

Just realized that I didn't open as draft. I'm still working on this. That's a first iteration.

I want to cut the changes short. I went out of line with the amount of lines.

@maciejburda
maciejburda force-pushed the maciej.burda/perfetto-empty-profile-probe branch 2 times, most recently from 924d948 to 159341b Compare August 7, 2026 09:32
@maciejburda maciejburda changed the title Detect empty Perfetto profiles on device Drop profiles that contain no callstack samples Aug 7, 2026
Some captures come back with the profiler having run at full cadence for the
whole window and produced no perf_sample at all. The one that prompted this is
1.19 MiB of payload-free packets over 57s, so neither file size nor packet
count tells it apart from a healthy capture.

PerfSampleProbe walks the trace framing and reports whether any
TracePacket.perf_sample is present. ProfilingDataWriter reports the verdict and
the trace size on the profiling write metric, on the path where the profile is
actually uploaded, so the SDK count of empty captures lines up with the count
the backend derives on its own. Agreement validates the walk, and the size
distribution gives the largest empty profile seen in the field.

Nothing is dropped. Only a verdict of no_samples would ever justify dropping,
and that decision waits until the rate has been observed, following the same
observe-then-enforce order the clock-drift gate used in this file.

Temporary, and one file to delete once the platform stops producing these.

Validated against two complete unmodified captures, checked in as the archives
the profiler produced. Their sample counts, 0 and 51304, come from Perfetto's
own trace_processor.
@maciejburda
maciejburda force-pushed the maciej.burda/perfetto-empty-profile-probe branch from 159341b to d2a9f6b Compare August 7, 2026 11:05
@maciejburda maciejburda changed the title Drop profiles that contain no callstack samples Measure how often captured profiles contain no samples Aug 7, 2026
@maciejburda maciejburda changed the title Measure how often captured profiles contain no samples Mesure profiles that contain no callstack samples using heuristic Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants