Skip to content

Commit 318ad7f

Browse files
committed
Support symbolicating .json.gz files.
1 parent 3aa20cd commit 318ad7f

File tree

8 files changed

+2089
-14
lines changed

8 files changed

+2089
-14
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
"@types/common-tags": "^1.8.4",
123123
"@types/jest": "^30.0.0",
124124
"@types/minimist": "^1.2.5",
125+
"@types/node": "^22.17.2",
125126
"@types/query-string": "^6.3.0",
126127
"@types/react": "^18.3.24",
127128
"@types/react-dom": "^18.3.1",

src/profile-logic/process-profile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2001,7 +2001,7 @@ export async function unserializeProfileOfArbitraryFormat(
20012001
arbitraryFormat = convertSimpleperfTraceProfile(arrayBuffer);
20022002
} else {
20032003
try {
2004-
const textDecoder = new TextDecoder();
2004+
const textDecoder = new TextDecoder(undefined, { fatal: true });
20052005
arbitraryFormat = await textDecoder.decode(arrayBuffer);
20062006
} catch (e) {
20072007
console.error('Source exception:', e);

src/symbolicator-cli/index.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,21 @@ export interface CliOptions {
7979

8080
export async function run(options: CliOptions) {
8181
console.log(`Loading profile from ${options.input}`);
82-
const serializedProfile = JSON.parse(fs.readFileSync(options.input, 'utf8'));
83-
const profile = await unserializeProfileOfArbitraryFormat(serializedProfile);
82+
83+
// Read the raw bytes from the file. It might be a JSON file, but it could also
84+
// be a binary file, e.g. a .json.gz file, or any of the binary formats supported
85+
// by our importers.
86+
const bytes = fs.readFileSync(options.input, null);
87+
88+
// bytes is a Uint8Array whose underlying ArrayBuffer can be longer than bytes.length.
89+
// Copy the contents into a new ArrayBuffer which is sized correctly, so that we
90+
// don't include uninitialized data from the extra parts of the underlying buffer.
91+
// Alternatively, we could make unserializeProfileOfArbitraryFormat support
92+
// Uint8Array or Buffer in addition to ArrayBuffer.
93+
const byteBufferCopy = Uint8Array.prototype.slice.call(bytes).buffer;
94+
95+
// Load the profile.
96+
const profile = await unserializeProfileOfArbitraryFormat(byteBufferCopy);
8497
if (profile === undefined) {
8598
throw new Error('Unable to parse the profile.');
8699
}

src/test/fixtures/node-worker.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import { Worker as NodeWorkerClass } from 'worker_threads';
5+
import {
6+
Worker as NodeWorkerClass,
7+
isMarkedAsUntransferable,
8+
} from 'worker_threads';
69

710
function getWorkerScript(file: string): string {
811
return `
@@ -52,7 +55,11 @@ export class NodeWorker {
5255
if (+major < 11 || (+major === 11 && +minor < 12)) {
5356
payload = { data: message };
5457
}
55-
this._instance?.postMessage(payload, transfer);
58+
// See https://github.com/nodejs/node/issues/55593
59+
const actualTransfer = (transfer ?? []).filter(
60+
(buf) => !isMarkedAsUntransferable(buf)
61+
);
62+
this._instance?.postMessage(payload, actualTransfer);
5663
}
5764

5865
onMessage = (message: unknown) => {

0 commit comments

Comments
 (0)