Split out of #619, which fixed the same class of mistake in the CPU sample index. This one is in the combined report and is arguably worse: it silently disables hang↔commit correlation entirely.
packages/tool-server/src/utils/profiler-shared/time-align.ts:50-58 — buildReactAnchor sets:
monotonicStartMs: cpuProfileStartTimeUs / 1000
and reactTimeToWallClock (:20-23) then computes reactWallStart + (commitMs - monotonicStartMs).
But React commit timestamps are already profile-relative — React DevTools emits every commit as performance.now() - profilingStartTime — while cpuProfileStartTimeUs is a since-boot monotonic value. On a real device that is ~1.28e12 µs (≈14.8 days of uptime, measured). So every commit is projected roughly one device-uptime into the past, windowsOverlap can never fire, and no hang can ever be correlated with a commit.
The correct value is monotonicStartMs: 0, matching the reasoning already applied in buildIosAnchor / buildPerfettoAnchor (:64-81).
Why no test caught it
test/ios-instruments/combined-report-frozen-anchor.test.ts:93 passes cpuProfilePath: null, so profiler-combined-report.ts:213 computes cpuStartUs = 0 and the bug cancels out. A test with a non-null cpuProfilePath whose startTime is a realistic since-boot value would fail today.
Why it isn't the one-liner it looks like
With monotonicStartMs: 0, buildReactAnchor's second parameter becomes dead — and so does its only producer, the readCpuProfile call at profiler-combined-report.ts:161-163, whose sole consumer is :213. Leaving them means dead code plus a needless full parse of the CPU profile on every combined report; removing them grows the diff into a second file. Either is fine, but it is a judgement call rather than a typo fix, which is why it is filed rather than folded into #619.
Suggested: fix the anchor, delete the now-unused parameter and the readCpuProfile call, and add the regression test with a non-zero cpuProfilePath.
Split out of #619, which fixed the same class of mistake in the CPU sample index. This one is in the combined report and is arguably worse: it silently disables hang↔commit correlation entirely.
packages/tool-server/src/utils/profiler-shared/time-align.ts:50-58—buildReactAnchorsets:and
reactTimeToWallClock(:20-23) then computesreactWallStart + (commitMs - monotonicStartMs).But React commit timestamps are already profile-relative — React DevTools emits every commit as
performance.now() - profilingStartTime— whilecpuProfileStartTimeUsis a since-boot monotonic value. On a real device that is ~1.28e12 µs (≈14.8 days of uptime, measured). So every commit is projected roughly one device-uptime into the past,windowsOverlapcan never fire, and no hang can ever be correlated with a commit.The correct value is
monotonicStartMs: 0, matching the reasoning already applied inbuildIosAnchor/buildPerfettoAnchor(:64-81).Why no test caught it
test/ios-instruments/combined-report-frozen-anchor.test.ts:93passescpuProfilePath: null, soprofiler-combined-report.ts:213computescpuStartUs = 0and the bug cancels out. A test with a non-nullcpuProfilePathwhosestartTimeis a realistic since-boot value would fail today.Why it isn't the one-liner it looks like
With
monotonicStartMs: 0,buildReactAnchor's second parameter becomes dead — and so does its only producer, thereadCpuProfilecall atprofiler-combined-report.ts:161-163, whose sole consumer is:213. Leaving them means dead code plus a needless full parse of the CPU profile on every combined report; removing them grows the diff into a second file. Either is fine, but it is a judgement call rather than a typo fix, which is why it is filed rather than folded into #619.Suggested: fix the anchor, delete the now-unused parameter and the
readCpuProfilecall, and add the regression test with a non-zerocpuProfilePath.