Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

metro-symbolicate

Package Overview
Dependencies
Maintainers
2
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

metro-symbolicate - npm Package Compare versions

Comparing version 0.56.3 to 0.57.0

src.real/__tests__/__fixtures__/hermes.js.hbc.map

4

package.json
{
"name": "metro-symbolicate",
"version": "0.56.3",
"version": "0.57.0",
"description": "A tool to find the source location from JS bundles and stack traces.",

@@ -24,3 +24,3 @@ "license": "MIT",

"invariant": "^2.2.4",
"metro-source-map": "0.56.3",
"metro-source-map": "0.57.0",
"source-map": "^0.5.6",

@@ -27,0 +27,0 @@ "through2": "^2.0.1",

@@ -58,3 +58,62 @@ /**

const TESTFILE_RAM_MAP = resolve('testfile.ram.js.map');
const HERMES_MAP = resolve('hermes.js.hbc.map');
const HERMES_MAP_CJS = resolve('hermescjs.js.hbc.map');
test('symbolicating a hermes stack trace', async () => {
const output = JSON.parse(
await execute(
[HERMES_MAP, '--hermes-crash'],
read('hermesStackTrace.json'),
),
);
expect(output).toMatchSnapshot();
});
test('symbolicating a hermes stack trace with input-line-start and input-column-start', async () => {
const output0Based = JSON.parse(
await execute(
[
HERMES_MAP,
'--hermes-crash',
'--input-line-start',
'0',
'--input-column-start',
'0',
],
read('hermesStackTrace.json'),
),
);
const output1Based = JSON.parse(
await execute(
[
HERMES_MAP,
'--hermes-crash',
'--input-line-start',
'1',
'--input-column-start',
'1',
],
read('hermesStackTrace.json'),
),
);
const outputNoFlag = JSON.parse(
await execute(
[HERMES_MAP, '--hermes-crash'],
read('hermesStackTrace.json'),
),
);
expect(outputNoFlag).toMatchObject(output0Based);
expect(outputNoFlag).toMatchObject(output1Based);
});
test('symbolicating a hermes stack trace CJS', async () => {
const output = JSON.parse(
await execute(
[HERMES_MAP_CJS, '--hermes-crash'],
read('hermesStackTraceCJS.json'),
),
);
expect(output).toMatchSnapshot();
});
test('symbolicating a stack trace', async () =>

@@ -61,0 +120,0 @@ await expect(

@@ -8,12 +8,2 @@ #!/usr/bin/env node

*
* Symbolicates a JavaScript stack trace using a source map.
* In our first form, we read a stack trace from stdin and symbolicate it via
* the provided source map.
* In our second form, we symbolicate using an explicit line number, and
* optionally a column.
* In our third form, we symbolicate using a module ID, a line number, and
* optionally a column.
*
* See https://our.intern.facebook.com/intern/dex/symbolicating-javascript-stack-traces-for-react-native/
*
* @flow strict-local

@@ -23,2 +13,10 @@ * @format

// Symbolicates a JavaScript stack trace using a source map.
// In our first form, we read a stack trace from stdin and symbolicate it via
// the provided source map.
// In our second form, we symbolicate using an explicit line number, and
// optionally a column.
// In our third form, we symbolicate using a module ID, a line number, and
// optionally a column.
'use strict';

@@ -45,3 +43,3 @@

} = process,
) {
): Promise<number> {
const argv = argvInput.slice();

@@ -64,2 +62,3 @@ function checkAndRemoveArg(arg, valuesPerArg = 0) {

const noFunctionNames = checkAndRemoveArg('--no-function-names');
const isHermesCrash = checkAndRemoveArg('--hermes-crash');
const inputLineStart = Number.parseInt(

@@ -98,2 +97,3 @@ checkAndRemoveArgWithValue('--input-line-start') || '1',

' --no-function-names',
' --hermes-crash',
' --input-line-start <line> (default: 1)',

@@ -134,3 +134,11 @@ ' --input-column-start <column> (default: 0)',

const stackTrace = await readAll(stdin);
stdout.write(context.symbolicate(stackTrace));
if (isHermesCrash) {
const stackTraceJSON = JSON.parse(stackTrace);
const symbolicatedTrace = context.symbolicateHermesMinidumpTrace(
stackTraceJSON,
);
stdout.write(JSON.stringify(symbolicatedTrace));
} else {
stdout.write(context.symbolicate(stackTrace));
}
} else if (argv[0].endsWith('.profmap')) {

@@ -137,0 +145,0 @@ stdout.write(context.symbolicateProfilerMap(argv[0]));

@@ -19,3 +19,3 @@ /**

import type {MixedSourceMap} from 'metro-source-map';
import type {MixedSourceMap, HermesFunctionOffsets} from 'metro-source-map';
// flowlint-next-line untyped-type-import:off

@@ -45,2 +45,32 @@ import {typeof SourceMapConsumer} from 'source-map';

type HermesMinidumpCrashInfo = {
+callstack: $ReadOnlyArray<HermesMinidumpStackFrame | NativeCodeStackFrame>,
};
type HermesMinidumpStackFrame = $ReadOnly<{|
ByteCodeOffset: number,
FunctionID: number,
CJSModuleOffset: number,
SourceURL: string,
StackFrameRegOffs: string,
SourceLocation?: string,
|}>;
type NativeCodeStackFrame = $ReadOnly<{|
NativeCode: true,
StackFrameRegOffs: string,
|}>;
type SymbolicatedStackTrace = $ReadOnlyArray<
SymbolicatedStackFrame | NativeCodeStackFrame,
>;
type SymbolicatedStackFrame = $ReadOnly<{|
line: ?number,
column: ?number,
source: ?string,
functionName: ?string,
name: ?string,
|}>;
const UNKNOWN_MODULE_IDS: SingleMapModuleIds = {

@@ -319,2 +349,12 @@ segmentId: 0,

/*
* Symbolicates the JavaScript stack trace extracted from the minidump
* produced by hermes
*/
symbolicateHermesMinidumpTrace(
crashInfo: HermesMinidumpCrashInfo,
): SymbolicatedStackTrace {
throw new Error('Not implemented');
}
/*
* An internal helper function similar to getOriginalPositionFor. This one

@@ -328,9 +368,3 @@ * returns both `name` and `functionName` fields so callers can distinguish the

moduleIds: ?ModuleIdsT,
): {|
line: ?number,
column: ?number,
source: ?string,
name: ?string,
functionName: ?string,
|} {
): SymbolicatedStackFrame {
throw new Error('Not implemented');

@@ -350,4 +384,6 @@ }

+sourceFunctionsConsumer: ?SourceMetadataMapConsumer,
+hermesOffsets: ?HermesFunctionOffsets,
|},
};
+_hasLegacySegments: boolean;

@@ -365,2 +401,3 @@ constructor(

: sourceMapContent;
const {x_hermes_function_offsets} = sourceMapJson;
const segments = {

@@ -373,2 +410,3 @@ '0': {

: null,
hermesOffsets: x_hermes_function_offsets,
},

@@ -385,8 +423,61 @@ };

: null,
hermesOffsets: map.x_hermes_function_offsets,
};
}
}
this._hasLegacySegments = sourceMapJson.x_facebook_segments != null;
this._segments = segments;
}
symbolicateHermesMinidumpTrace(
crashInfo: HermesMinidumpCrashInfo,
): SymbolicatedStackTrace {
const symbolicatedTrace = [];
const {callstack} = crashInfo;
if (callstack != null) {
for (const stackItem of callstack) {
if (stackItem.NativeCode) {
symbolicatedTrace.push(stackItem);
} else {
const {
CJSModuleOffset,
SourceURL,
FunctionID,
ByteCodeOffset: localOffset,
} = stackItem;
const moduleInformation = this._hasLegacySegments
? this.parseFileName(SourceURL)
: UNKNOWN_MODULE_IDS;
const generatedLine = CJSModuleOffset + this.options.inputLineStart;
const segment = this._segments[
moduleInformation.segmentId.toString()
];
const hermesOffsets = segment?.hermesOffsets;
if (!hermesOffsets) {
symbolicatedTrace.push({
line: null,
column: null,
source: null,
functionName: null,
name: null,
});
} else {
const segmentOffsets = hermesOffsets[Number(CJSModuleOffset)];
const generatedColumn =
segmentOffsets[FunctionID] +
localOffset +
this.options.inputColumnStart;
const originalPosition = this.getOriginalPositionDetailsFor(
generatedLine,
generatedColumn,
moduleInformation,
);
symbolicatedTrace.push(originalPosition);
}
}
}
}
return symbolicatedTrace;
}
/*

@@ -401,9 +492,3 @@ * An internal helper function similar to getOriginalPositionFor. This one

moduleIds: ?SingleMapModuleIds,
): {|
line: ?number,
column: ?number,
source: ?string,
name: ?string,
functionName: ?string,
|} {
): SymbolicatedStackFrame {
// Adjust arguments to source-map's input coordinates

@@ -509,9 +594,3 @@ lineNumber =

filename: ?string,
): {|
line: ?number,
column: ?number,
source: ?string,
name: ?string,
functionName: ?string,
|} {
): SymbolicatedStackFrame {
invariant(

@@ -518,0 +597,0 @@ filename != null,

@@ -9,15 +9,12 @@ #!/usr/bin/env node

*
* Symbolicates a JavaScript stack trace using a source map.
* In our first form, we read a stack trace from stdin and symbolicate it via
* the provided source map.
* In our second form, we symbolicate using an explicit line number, and
* optionally a column.
* In our third form, we symbolicate using a module ID, a line number, and
* optionally a column.
*
* See https://our.intern.facebook.com/intern/dex/symbolicating-javascript-stack-traces-for-react-native/
*
* strict-local
* @format
*/
// Symbolicates a JavaScript stack trace using a source map.
// In our first form, we read a stack trace from stdin and symbolicate it via
// the provided source map.
// In our second form, we symbolicate using an explicit line number, and
// optionally a column.
// In our third form, we symbolicate using a module ID, a line number, and
// optionally a column.
"use strict"; // flowlint-next-line untyped-import:off

@@ -107,2 +104,3 @@

const noFunctionNames = checkAndRemoveArg("--no-function-names");
const isHermesCrash = checkAndRemoveArg("--hermes-crash");
const inputLineStart = Number.parseInt(

@@ -140,2 +138,3 @@ checkAndRemoveArgWithValue("--input-line-start") || "1",

" --no-function-names",
" --hermes-crash",
" --input-line-start <line> (default: 1)",

@@ -177,3 +176,12 @@ " --input-column-start <column> (default: 0)",

const stackTrace = yield readAll(stdin);
stdout.write(context.symbolicate(stackTrace));
if (isHermesCrash) {
const stackTraceJSON = JSON.parse(stackTrace);
const symbolicatedTrace = context.symbolicateHermesMinidumpTrace(
stackTraceJSON
);
stdout.write(JSON.stringify(symbolicatedTrace));
} else {
stdout.write(context.symbolicate(stackTrace));
}
} else if (argv[0].endsWith(".profmap")) {

@@ -180,0 +188,0 @@ stdout.write(context.symbolicateProfilerMap(argv[0]));

@@ -316,2 +316,10 @@ /**

/*
* Symbolicates the JavaScript stack trace extracted from the minidump
* produced by hermes
*/
symbolicateHermesMinidumpTrace(crashInfo) {
throw new Error("Not implemented");
}
/*
* An internal helper function similar to getOriginalPositionFor. This one

@@ -341,2 +349,3 @@ * returns both `name` and `functionName` fields so callers can distinguish the

: sourceMapContent;
const x_hermes_function_offsets = sourceMapJson.x_hermes_function_offsets;
const segments = {

@@ -348,3 +357,4 @@ "0": {

? new SourceMetadataMapConsumer(sourceMapJson)
: null
: null,
hermesOffsets: x_hermes_function_offsets
}

@@ -361,3 +371,4 @@ };

? new SourceMetadataMapConsumer(map)
: null
: null,
hermesOffsets: map.x_hermes_function_offsets
};

@@ -367,4 +378,60 @@ }

this._hasLegacySegments = sourceMapJson.x_facebook_segments != null;
this._segments = segments;
}
symbolicateHermesMinidumpTrace(crashInfo) {
const symbolicatedTrace = [];
const callstack = crashInfo.callstack;
if (callstack != null) {
for (const stackItem of callstack) {
if (stackItem.NativeCode) {
symbolicatedTrace.push(stackItem);
} else {
const CJSModuleOffset = stackItem.CJSModuleOffset,
SourceURL = stackItem.SourceURL,
FunctionID = stackItem.FunctionID,
localOffset = stackItem.ByteCodeOffset;
const moduleInformation = this._hasLegacySegments
? this.parseFileName(SourceURL)
: UNKNOWN_MODULE_IDS;
const generatedLine = CJSModuleOffset + this.options.inputLineStart;
const segment = this._segments[
moduleInformation.segmentId.toString()
];
const hermesOffsets =
segment === null || segment === void 0
? void 0
: segment.hermesOffsets;
if (!hermesOffsets) {
symbolicatedTrace.push({
line: null,
column: null,
source: null,
functionName: null,
name: null
});
} else {
const segmentOffsets = hermesOffsets[Number(CJSModuleOffset)];
const generatedColumn =
segmentOffsets[FunctionID] +
localOffset +
this.options.inputColumnStart;
const originalPosition = this.getOriginalPositionDetailsFor(
generatedLine,
generatedColumn,
moduleInformation
);
symbolicatedTrace.push(originalPosition);
}
}
}
}
return symbolicatedTrace;
}
/*

@@ -371,0 +438,0 @@ * An internal helper function similar to getOriginalPositionFor. This one

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc