Deploy May 26, 2026#6061
Merged
Merged
Conversation
Drops dependencies and devDependencies with no remaining importers, plus the now-orphaned @types/react-splitter-layout resolution. - url, weaktuplemap (no imports anywhere in src/scripts/profiler-cli) - @babel/cli (build pipeline is esbuild, not babel CLI) - @babel/plugin-proposal-class-properties (superseded by @babel/plugin-transform-class-properties referenced in babel.config.json) - @types/react-splitter-layout (the runtime package is no longer a dependency and SplitterLayout is not used in src/) - mkdirp (no references in scripts or configs)
Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.0.6 to 3.1.2. - [Release notes](https://github.com/fastify/fast-uri/releases) - [Commits](fastify/fast-uri@v3.0.6...v3.1.2) --- updated-dependencies: - dependency-name: fast-uri dependency-version: 3.1.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…6014) Bumps [@babel/plugin-transform-modules-systemjs](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs) from 7.29.0 to 7.29.4. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.29.4/packages/babel-plugin-transform-modules-systemjs) --- updated-dependencies: - dependency-name: "@babel/plugin-transform-modules-systemjs" dependency-version: 7.29.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Daemon process is the one that does all the network requests, and it looks like all the sandboxed environments use an environment proxy for allowed/disallowed domains using `HTTP_PROXY/HTTPS_PROXY`. I was a bit suspicious at first thinking that maybe this is not great security-wise, but then learned that this is the deafult behavior pretty much everywhere except for node, and node is considering about turning it on by default. For example, this is the default in curl, python, go, and in popular rust packages like reqwest. The rationale is that, if they have access to your machine, setting this env vars is the least of your concern. For example, see the curl documentation: https://curl.se/docs/tutorial.html#:~:text=SPNEGO%29%2E-,Environment%20Variables
Previously, isProcessRunning used `kill(pid, 0)`, to check daemon is still alive, which returns EPERM in sandboxed environments regardless of whether the process actually exists. This commit replaces this check with a socket connection attempt. A connection failure (either ENOENT or ECONNREFUSED) successfully indicates a dead daemon on all platforms without requiring any signal permission. Also it replaces waitForProcessExit with waitForSocketClose, which polls the same connect probe. Updates validateSession to be async and use the new check, collapsing the separate PID and socket-file-existence checks into a single socket connect attempt.
There were two things that prevented us from having a working cli in the sandboxed environments: 1. HTTP(S) proxy needs to be used - All network request must go through some proxy, so the sandboxed environment can choose to allow or block the requests per domain. If it doesn't use this proxy, the requests are usually blocked automatically without a way to allow. It seemed a bit sketchy to me at first but then I realized that this is the default behavior on many places like curl, python, go, and node is considering enabling this by default. 2. Signaling a process is not allowed - `process.kill(pid, 0);` isn't allowed in sandboxed environments, so this can't be used to check if the process is still alive. Instead, I converted that `isProcessRunning` to `isDaemonReachable` and used the existing sockets to check if the daemon is still listening that socket (for example with ECONNREFUSED). Also please see the individual commit messages. I tested both on macOS and Linux, and they seem to work (with some additional config depending on what you use for sandboxing)
…#6015) `profiler-edit` was just writing out the profile with `JSON.stringify`, which is different from what the front-end does when you download the profile - the front-end goes through profile sanitization, which also runs compacting. You can see in the snapshot tests that running compacting removes some unused strings from the stringArray.
Numbers from my machine: `yarn prettier-fix` before: 6.5 seconds `yarn fmt` after: 1.3 seconds `yarn lint-fix` is still slow (9 seconds), I think that's bottlenecked on eslint.
Numbers from my machine: `yarn prettier-fix` before: 6.5 seconds `yarn fmt` after: 1.3 seconds `yarn lint-fix` is still slow (9 seconds), I think that's bottlenecked on eslint.
This allows applying wasm symbols to existing profiles that were captured with a stripped wasm bundle. The script looks for functions with names of the shape `wasm-function[123]`, which is what Firefox uses when the wasm file doesn't have a names section. Usage: ``` yarn build-node-tools && \ node node-tools-dist/profiler-edit.js -i input.json.gz \ --symbolicate-wasm http://host/a.wasm=./a-unstripped.wasm \ --symbolicate-wasm http://host/b.wasm=./b-unstripped.wasm \ -o out.json.gz ```
This allows applying wasm symbols to existing profiles that were captured with a stripped wasm bundle. The script looks for functions with names of the shape `wasm-function[123]`, which is what Firefox uses when the wasm file doesn't have a names section. Usage: ``` yarn build-node-tools && \ node node-tools-dist/profiler-edit.js -i input.json.gz \ --symbolicate-wasm http://host/a.wasm=./a-unstripped.wasm \ --symbolicate-wasm http://host/b.wasm=./b-unstripped.wasm \ -o out.json.gz ``` --- I've successfully used it to turn https://share.firefox.dev/4f9O7oh into https://share.firefox.dev/4nd6GKk .
This PR does similarly to what we did for the node tools artifact. It would be nice to have profiler-cli uploaded as an artifact for PRs etc so people can try it out easily for manual testing.
#6016) Here's a file which decompresses to a 605.8MB JSON string: [etw-speedometer3.json.gz](https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/FplSekLmRsm6lmh_2fKu7A/runs/0/artifacts/public/test_info/etw-speedometer3.json.gz) Loading this file in Chrome, or in node via profiler-edit, fails due to the string size. As a workaround we can use a streaming JSON parser which doesn't materialize a string for the entire thing.
Co-authored-by: Марко Костић (Marko Kostić) <marko.m.kostic@gmail.com> (sr)
Co-authored-by: YD <ygda+fx@free.fr> (fr)
Should make running tests less noisy (see https://bugzilla.mozilla.org/show_bug.cgi?id=2035950)
Should make running tests less noisy (see https://bugzilla.mozilla.org/show_bug.cgi?id=2035950)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 8.0.3 to 8.2.0. - [Release notes](https://github.com/protobufjs/protobuf.js/releases) - [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md) - [Commits](protobufjs/protobuf.js@protobufjs-v8.0.3...protobufjs-v8.2.0) --- updated-dependencies: - dependency-name: protobufjs dependency-version: 8.2.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
workbox-window 7.4.1 ships a UMD build without `__esModule: true` (a
side effect of the package's Rollup 2 -> 4 migration, since Rollup's
`output.esModule` default changed from `true` to `"if-default-prop"` and
workbox-window has no default export). Without the marker, Babel's
`_interopRequireWildcard` copies the module's exports for `import * as
WorkboxModule from 'workbox-window'`, so `jest.spyOn(WorkboxModule,
'Workbox')` mutated a copy while the source file's `import { Workbox }`
kept resolving to the real constructor.
Replace the namespace-spy with `jest.mock('workbox-window', ...)` so
both sides share the same mocked `Workbox`, and switch the per-test
implementation to `(Workbox as jest.Mock).mockImplementation(...)`.
Previously, hidden non-thread tracks (screenshots, network, IPC, marker) reappeared after publishing a sanitized profile when sanitization also removed a thread: the URL state's hidden-track sets and track-order were reset whenever threads were re-indexed, even though the non-thread tracks still existed in the sanitized profile. When a tab filter was active, the bug also affected tracks in surviving processes because the `tabToThreadIndexesMap` used to filter the new global track list still referenced pre-sanitization thread indexes. `attemptToPublish` now builds an old-to-new `TrackIndex` map by matching tracks on stable identity (pid, screenshot id, threadIndex, counterIndex, visual-progress singleton, or marker schema name plus marker name string) and translates `hiddenGlobalTracks`, `globalTrackOrder`, `hiddenLocalTracksByPid`, and `localTrackOrderByPid` through it on `SANITIZED_PROFILE_PUBLISHED`. Old-side thread, counter, and string-table indexes are normalized through the maps in `ProfileIndexTranslationMaps` before comparison. The `tabToThreadIndexesMap` is rebuilt from the sanitized profile's threads and pages so its `ThreadIndex` values are valid in the new track-index space; the `innerWindowID → tabID` computation is extracted into a shared `computeInnerWindowIDToTabMap` helper that the existing `getInnerWindowIDToTabMap` selector also uses. Fixes #2947
Fixes #6035. I broke this in the move to the shared tables. We were mutating the frameTable + funcTable + stackTable from an empty profile, and then throwing out our mutated tables by replacing them with the empty tables from the globalDataCollector.
…OMNode (#5988) findDOMNode is deprecated in React 18 and removed in React 19 strict mode, and withSize was the last in-tree caller. withSize now renders a `<div style="display: contents">` around the wrapped component and observes `wrapper.firstElementChild` via the existing ResizeObserver wrapper, and is converted to a function component. EmptyThreadIndicator and Timeline tests mocked findDOMNode to inject sizes; those mocks silently became no-ops once findDOMNode was gone and are replaced with autoMockElementSize. --------- Co-authored-by: fatadel <afatkhutdinov@mozilla.com>
Co-authored-by: Ali Demirtaş <alidemirtas94@gmail.com> (tr)
[Production](https://profiler.firefox.com/from-url/https%3A%2F%2Fraw.githubusercontent.com%2Ffirefox-devtools%2Fprofiler%2Frefs%2Fheads%2Fmain%2Fsrc%2Ftest%2Ffixtures%2Fupgrades%2Fdhat.json.gz/) | [Deploy preview](https://deploy-preview-6036--perf-html.netlify.app/from-url/https%3A%2F%2Fraw.githubusercontent.com%2Ffirefox-devtools%2Fprofiler%2Frefs%2Fheads%2Fmain%2Fsrc%2Ftest%2Ffixtures%2Fupgrades%2Fdhat.json.gz/) Fixes #6035. I broke this in the move to the shared tables. We were mutating the frameTable + funcTable + stackTable from an empty profile, and then throwing out our mutated tables by replacing them with the empty tables from the globalDataCollector.
Some frames in a profile are inlined into their caller's machine code by the compiler. The profiler frontend marks these with a small "inl" badge and a tooltip naming the outer function, but the CLI previously gave no hint, so consumers could not tell that an inlined frame's body actually executes inside another function and would treat it as an independent call site. Each call tree node and heaviest-stack frame now carries an `inlineStatus` of `'inlined'` or `'divergent'`, derived from `CallNodeInfo.sourceFramesInlinedIntoSymbolForNode` The CLI formatter appends `(inl)` or `(inl?)` after the function name and, when at least one frame in the output is inlined, prints a one-line legend above the tree / heaviest stack explaining the markers.
Bumps [@tootallnate/once](https://github.com/TooTallNate/once) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/TooTallNate/once/releases) - [Changelog](https://github.com/TooTallNate/once/blob/v2.0.1/CHANGELOG.md) - [Commits](TooTallNate/once@2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: "@tootallnate/once" dependency-version: 2.0.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ali Demirtaş <alidemirtas94@gmail.com> (tr)
I think we wrote these tests when we didn't have proper types, and they were never added here. This patch adds proper types also to make sure that we will catch any type errors in the future.
…6044) TextMeasurement's width cache was a plain object, so looking up `_cache["toString"]` returned Object.prototype.toString instead of undefined. getFittedText treated that function as a cached width, which collapsed the truncation algorithm and produced just "…". This affected JS frames whose names collide with Object.prototype: toString, hasOwnProperty, valueOf, constructor, isPrototypeOf, propertyIsEnumerable, toLocaleString, __proto__. Visible in the flame graph, stack chart, marker chart, and js-tracer canvases. Switching the cache to a Map solves this problem.
Seven of the ten error cases in the errors.map() were missing a key prop on their Localized wrapper, and that was causing a React dev warning about non-unique keys in a list.
Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Bumps [qs](https://github.com/ljharb/qs) from 6.14.2 to 6.15.2. - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](ljharb/qs@v6.14.2...v6.15.2) --- updated-dependencies: - dependency-name: qs dependency-version: 6.15.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updated locales: fr, sr, tr, zh-CN.
`function annotate --mode asm` always fell back to the hardcoded `http://localhost:3000` when `--symbol-server` wasn't passed to the annotate command, and ignored both `?symbolServer=` from a loaded profiler.firefox.com URL and `--symbol-server` passed to `pq load`. This commit changes the cli to resolve the symbol server inside `ProfileQuerier.functionAnnotate` via `getSymbolServerUrl` when no explicit URL is provided, so the value set by either source on the URL state is taken into account. An explicit `--symbol-server` on `function annotate` still overrides.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes:
[fatadel] Remove unused dependencies from package.json (#6010)
[Nazım Can Altınova] Make profiler-cli work in sandboxed environments (#6003)
[Markus Stange] Make profiler-edit run profile compacting before writing out the file (#6015)
[Markus Stange] Migrate from prettier to oxfmt (#5986)
[Markus Stange] Add a --symbolicate-wasm arg to profiler-edit. (#6008)
[Markus Stange] Build and upload the cli artifact in PRs (#6020)
[Markus Stange] Use @streamparser/json if the input is too large to fit in a V8 string (#6016)
[Nazım Can Altınova] Print also the status output right after cli
loadcommand (#6019)[Nicolas Chevobbe] Update devtools-reps to 0.27.7 (#6030)
[Nazım Can Altınova] Include
--searchoption inpq filter push(#6026)[Nazım Can Altınova] Update all Yarn dependencies (2026-05-20) (#6033)
[fatadel] Translate URL track-index state through profile sanitization (#6000)
[Markus Stange] Make withSize use a wrapper element so that it can stop calling findDOMNode (#5988)
[Markus Stange] Fix dhat importer (#6036)
[Nazım Can Altınova] Annotate inlined frames in CLI call trees and stacks (#6041)
[Nazım Can Altınova] Use proper types in cli tests instead of custom inline types (#6038)
[Nazım Can Altınova] Fix text truncation for frames named after Object.prototype methods (#6044)
[Nazım Can Altınova] Add missing key props to CodeErrorOverlay error list items (#6047)
[depfu[bot]] ⬆️ Update oxfmt to version 0.51.0 (#6054)
[Nazım Can Altınova] 🔃 Sync: l10n -> main (May 26, 2026) (#6058)
[Nazım Can Altınova] Use URL-state symbol server for
profiler-cli function annotate(#6051)[Nazım Can Altınova] Bump profiler-cli version to 0.2.0 (#6059)
And special thanks to our localizers:
fr: YD
sr: Марко Костић (Marko Kostić)
tr: Ali Demirtaş
zh-CN: Olvcpr423
zh-CN: wxie