-55555 | shaping symbolicator

This commit is contained in:
varnit goyal
2024-11-09 17:33:58 +05:30
parent da9b7d9153
commit d6b8b807ea
22 changed files with 5279 additions and 12 deletions

6
.gitignore vendored
View File

@@ -29,3 +29,9 @@ go.sum
source-map-cache/
tmp/
node_modules
.idea
bins/cybertron-symbolicator-react-native/node_modules
bins/cybertron-symbolicator-react-native/.idea

4
.gitmodules vendored
View File

@@ -1,3 +1,7 @@
[submodule "cybertron-symbolicator"]
path = cybertron-symbolicator
url = git@github.com:navi-ppl/cybertron-symbolicator.git
[submodule "cybertron-symbolicator-react-native"]
path = cybertron-symbolicator-react-native
url = git@github.com:navi-ppl/cybertron-symbolicator-react-native.git

View File

@@ -0,0 +1,43 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="log-enricher-go-land" type="GoApplicationRunConfiguration" factoryName="Go Application">
<module name="cybertron" />
<working_directory value="$PROJECT_DIR$" />
<envs>
<env name="AWS_BUCKET" value="navi-cd955a63c4476df0f00c1cea0e4a40d1" />
<env name="AWS_REGION" value="ap-south-1" />
<env name="DB_HOST" value="localhost" />
<env name="DB_NAME" value="cybertron_dev" />
<env name="DB_PASSWORD" value="admin" />
<env name="DB_USERNAME" value="postgres" />
<env name="ELASTIC_ADDRESS" value="https://office-server.tail3fba9.ts.net:9200" />
<env name="ELASTIC_API_KEY" value="" />
<env name="ELASTIC_INDEX" value="cybertron" />
<env name="ELASTIC_PASSWORD" value="9457611267" />
<env name="ELASTIC_USERNAME" value="elastic" />
<env name="ENV" value="local" />
<env name="HOUSTON_REALM_ID" value="ZicSxsvBwE" />
<env name="HOUSTON_SERVICE_URL" value="https://qa-houston.np.navi-sa.in" />
<env name="KAFKA_BROKERS" value="cell-1.streaming.ap-mumbai-1.oci.oraclecloud.com:9092" />
<env name="KAFKA_GROUP" value="kafka-stream" />
<env name="KAFKA_PASSWORD" value="" />
<env name="KAFKA_SASL_MECHANISM" value="PLAIN" />
<env name="KAFKA_TOPIC" value="kafka-stream" />
<env name="KAFKA_USERNAME" value="varnitgoyal/varnitgoyal95@gmail.com/ocid1.streampool.oc1.ap-mumbai-1.amaaaaaaotdslraanepwp54txqqxkmg4l6dghrhufiezqkx2lqhndgxoq7pa" />
<env name="METRICS_PORT" value="4001" />
<env name="MJOLNIR_REALM" value="ZicSxsvBwE" />
<env name="MJOLNIR_SERVICE_URL" value="https://qa-mjolnir-service.np.navi-ppl.in" />
<env name="NAME" value="cybertron" />
<env name="PORT" value="9001" />
<env name="PROMETHEUS_APP_NAME" value="cybertron" />
<env name="PROMETHEUS_HOST" value="localhost" />
<env name="PROMETHEUS_POST" value="4001" />
</envs>
<kind value="PACKAGE" />
<package value="log-enricher/cmd/log-enricher" />
<directory value="$PROJECT_DIR$" />
<filePath value="$PROJECT_DIR$" />
<method v="2">
<option name="ToolBeforeRunTask" enabled="true" actionId="Tool_External Tools_node modules install" />
</method>
</configuration>
</component>

View File

@@ -1,10 +1,10 @@
ARG GOLANG_TAG=193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/golang:1.22.4
ARG GOLANG_TAG=golang:1.22.4
ARG NODE_JS_TAG=node:18.15.0-alpine3.16
# To run locally, use
#ARG GOLANG_TAG=registry.cmd.navi-tech.in/common/golang:1.19
FROM ${GOLANG_TAG} as builder
FROM ${GOLANG_TAG} AS builder
RUN mkdir -p /build
WORKDIR /build
COPY . /build
@@ -25,17 +25,30 @@ RUN cd cybertron-symbolicator \
&& strip source-map
FROM ${NODE_JS_TAG} AS node-cache-builder
RUN mkdir /cache
WORKDIR /cache
COPY cybertron-symbolicator-react-native/package.json /cache
COPY cybertron-symbolicator-react-native/yarn.lock /cache
RUN npm install
FROM ${GOLANG_TAG}
FROM node:20-bookworm
RUN mkdir -p /usr/local
WORKDIR /usr/local
COPY --from=0 /build/out/log-enricher /usr/local/
COPY --from=0 /build/out/migrations /usr/local/migrations
COPY --from=0 /build/db/migrations/*.sql /usr/local/db/migrations/
COPY --from=0 /build/configs/application.yml /usr/local/configs/
COPY --from=builder /build/out/log-enricher /usr/local/
COPY --from=builder /build/out/migrations /usr/local/migrations
COPY --from=builder /build/db/migrations/*.sql /usr/local/db/migrations/
COPY --from=builder /build/configs/application.yml /usr/local/configs/
RUN mkdir -p /usr/local/bins/cybertron-symbolicator-react-native
COPY --from=builder /build/cybertron-symbolicator-react-native /usr/local/bins/cybertron-symbolicator-react-native
COPY --from=node-cache-builder /cache/ /usr/local/bins/cybertron-symbolicator-react-native/
COPY --from=symbolicator-builder /src/cybertron-symbolicator/source-map /usr/local/bins/
RUN adduser --system --uid 4000 --disabled-password api-user && chown -R 4000:4000 /usr/local && chmod -R g+w /usr/local/
USER 4000
CMD /bin/bash -c "./log-enricher"

View File

@@ -39,6 +39,14 @@ go install github.com/air-verse/air@latest
air
```
## How to build on local using docker
Remove double quotes from kafka-password if it contians special characters
```shell
docker build . -t log-enricher
docker run log-enricher --env-file local.env
```

View File

@@ -0,0 +1,2 @@
node_modules
yarn

View File

@@ -0,0 +1,361 @@
"use strict";
const invariant = require("invariant");
const CHILDREN_FIELD_TYPE = "__CHILDREN__";
class ChromeHeapSnapshotProcessor {
constructor(snapshotData) {
this._snapshotData = snapshotData;
this._globalStringTable = new ChromeHeapSnapshotStringTable(
this._snapshotData.strings
);
}
traceFunctionInfos() {
return new ChromeHeapSnapshotRecordIterator(
this._snapshotData.trace_function_infos,
this._snapshotData.snapshot.meta.trace_function_info_fields,
{
name: "string",
script_name: "string",
},
this._globalStringTable,
undefined
);
}
locations() {
return new ChromeHeapSnapshotRecordIterator(
this._snapshotData.locations,
this._snapshotData.snapshot.meta.location_fields,
null,
this._globalStringTable,
undefined
);
}
nodes() {
return new ChromeHeapSnapshotRecordIterator(
this._snapshotData.nodes,
this._snapshotData.snapshot.meta.node_fields,
this._snapshotData.snapshot.meta.node_types,
this._globalStringTable,
undefined
);
}
edges() {
return new ChromeHeapSnapshotRecordIterator(
this._snapshotData.edges,
this._snapshotData.snapshot.meta.edge_fields,
this._snapshotData.snapshot.meta.edge_types,
this._globalStringTable,
undefined
);
}
traceTree() {
return new ChromeHeapSnapshotRecordIterator(
this._snapshotData.trace_tree,
this._snapshotData.snapshot.meta.trace_node_fields,
{
children: CHILDREN_FIELD_TYPE,
},
this._globalStringTable,
undefined
);
}
}
class ChromeHeapSnapshotStringTable {
constructor(strings) {
this._strings = strings;
this._indexCache = new Map();
}
add(value) {
this._syncIndexCache();
let index = this._indexCache.get(value);
if (index != null) {
return index;
}
index = this._strings.length;
this._strings.push(value);
this._indexCache.set(value, index);
return index;
}
get(index) {
invariant(
index >= 0 && index < this._strings.length,
"index out of string table range"
);
return this._strings[index];
}
_syncIndexCache() {
if (this._strings.length > this._indexCache.size) {
for (let i = this._indexCache.size; i < this._strings.length; ++i) {
this._indexCache.set(this._strings[i], i);
}
}
}
}
class ChromeHeapSnapshotRecordAccessor {
constructor(
buffer,
recordFields,
recordTypes,
globalStringTable,
position,
parent
) {
if (parent) {
this._recordSize = parent._recordSize;
this._fieldToOffset = parent._fieldToOffset;
this._fieldToType = parent._fieldToType;
} else {
this._recordSize = recordFields.length;
this._fieldToOffset = new Map(
Object.entries(recordFields).map(([offsetStr, name]) => [
String(name),
Number(offsetStr),
])
);
if (Array.isArray(recordTypes)) {
this._fieldToType = new Map(
Object.entries(recordTypes).map(([offsetStr, type]) => [
recordFields[Number(offsetStr)],
type,
])
);
} else {
this._fieldToType = new Map(Object.entries(recordTypes || {}));
}
}
this._buffer = buffer;
this._position = position;
invariant(
this._position % this._recordSize === 0,
"Record accessor constructed at invalid offset"
);
invariant(
this._buffer.length % this._recordSize === 0,
"Record accessor constructed with wrong size buffer"
);
this._globalStringTable = globalStringTable;
}
getString(field) {
const dynamicValue = this._getScalar(field);
if (typeof dynamicValue === "string") {
return dynamicValue;
}
throw new Error("Not a string or enum field: " + field);
}
getNumber(field) {
const dynamicValue = this._getScalar(field);
if (typeof dynamicValue === "number") {
return dynamicValue;
}
throw new Error("Not a number field: " + field);
}
getChildren(field) {
const fieldType = this._fieldToType.get(field);
if (fieldType !== CHILDREN_FIELD_TYPE) {
throw new Error("Not a children field: " + field);
}
const childrenBuffer = this._getRaw(field);
invariant(
Array.isArray(childrenBuffer),
"Expected array in children-typed field"
);
return new ChromeHeapSnapshotRecordIterator(
childrenBuffer,
[],
null,
this._globalStringTable,
-this._fieldToOffset.size,
this
);
}
setString(field, value) {
this._setRaw(field, this._encodeString(field, value));
}
setNumber(field, value) {
const fieldType = this._fieldToType.get(field);
if (
Array.isArray(fieldType) ||
fieldType === "string" ||
fieldType === CHILDREN_FIELD_TYPE
) {
throw new Error("Not a number field: " + field);
}
this._setRaw(field, value);
}
moveToRecord(recordIndex) {
this._moveToPosition(recordIndex * this._recordSize);
}
append(record) {
const savedPosition = this._position;
try {
return this.moveAndInsert(this._buffer.length / this._recordSize, record);
} finally {
this._position = savedPosition;
}
}
moveAndInsert(recordIndex, record) {
this._moveToPosition(recordIndex * this._recordSize, true);
let didResizeBuffer = false;
try {
for (const field of this._fieldToOffset.keys()) {
if (!Object.prototype.hasOwnProperty.call(record, field)) {
throw new Error("Missing value for field: " + field);
}
}
this._buffer.splice(this._position, 0, ...new Array(this._recordSize));
didResizeBuffer = true;
for (const field of Object.keys(record)) {
this._set(field, record[field]);
}
return this._position / this._recordSize;
} catch (e) {
if (didResizeBuffer) {
this._buffer.splice(this._position, this._recordSize);
}
throw e;
}
}
protectedHasNext() {
if (this._position < 0) {
return this._buffer.length > 0;
}
return this._position < this._buffer.length;
}
protectedTryMoveNext() {
if (this.protectedHasNext()) {
this._moveToPosition(this._position + this._recordSize, true);
}
}
_getRaw(field) {
this._validatePosition();
const offset = this._fieldToOffset.get(field);
if (offset == null) {
throw new Error("Unknown field: " + field);
}
return this._buffer[this._position + offset];
}
_getScalar(field) {
const rawValue = this._getRaw(field);
if (Array.isArray(rawValue)) {
throw new Error("Not a scalar field: " + field);
}
const fieldType = this._fieldToType.get(field);
if (Array.isArray(fieldType)) {
invariant(
rawValue >= 0 && rawValue < fieldType.length,
"raw value does not match field enum type"
);
return fieldType[rawValue];
}
if (fieldType === "string") {
return this._globalStringTable.get(rawValue);
}
return rawValue;
}
_setRaw(field, rawValue) {
this._validatePosition();
const offset = this._fieldToOffset.get(field);
if (offset == null) {
throw new Error("Unknown field: " + field);
}
this._buffer[this._position + offset] = rawValue;
}
_set(field, value) {
if (typeof value === "string") {
this.setString(field, value);
} else if (typeof value === "number") {
this.setNumber(field, value);
} else if (Array.isArray(value)) {
this._setChildren(field, value);
} else {
throw new Error("Unsupported value for field: " + field);
}
}
_setChildren(field, value) {
const fieldType = this._fieldToType.get(field);
if (fieldType !== CHILDREN_FIELD_TYPE) {
throw new Error("Not a children field: " + field);
}
this._setRaw(field, []);
const childIt = this.getChildren(field);
for (const child of value) {
childIt.append(child);
}
}
_encodeString(field, value) {
const fieldType = this._fieldToType.get(field);
if (Array.isArray(fieldType)) {
const index = fieldType.indexOf(value);
invariant(index >= 0, "Cannot define new values in enum field");
return index;
}
if (fieldType === "string") {
return this._globalStringTable.add(value);
}
throw new Error("Not a string or enum field: " + field);
}
_validatePosition(allowEnd = false, position = this._position) {
if (!Number.isInteger(position)) {
throw new Error(`Position ${position} is not an integer`);
}
if (position % this._recordSize !== 0) {
throw new Error(
`Position ${position} is not a multiple of record size ${this._recordSize}`
);
}
if (position < 0) {
throw new Error(`Position ${position} is out of range`);
}
const maxPosition = allowEnd
? this._buffer.length
: this._buffer.length - 1;
if (position > maxPosition) {
throw new Error(`Position ${position} is out of range`);
}
if (this._buffer.length - position < this._recordSize) {
if (!(allowEnd && this._buffer.length === position)) {
throw new Error(
`Record at position ${position} is truncated: expected ${
this._recordSize
} fields but found ${this._buffer.length - position}`
);
}
}
}
_moveToPosition(nextPosition, allowEnd = false) {
this._validatePosition(allowEnd, nextPosition);
this._position = nextPosition;
}
}
class ChromeHeapSnapshotRecordIterator extends ChromeHeapSnapshotRecordAccessor {
constructor(
buffer,
recordFields,
recordTypes,
globalStringTable,
position = -recordFields.length,
parent
) {
super(
buffer,
recordFields,
recordTypes,
globalStringTable,
position,
parent
);
}
next() {
this.protectedTryMoveNext();
return {
done: !this.protectedHasNext(),
value: this,
};
}
[Symbol.iterator]() {
return this;
}
}
module.exports = {
ChromeHeapSnapshotProcessor,
};

View File

@@ -0,0 +1,50 @@
"use strict";
const { normalizeSourcePath } = require("./source-map.debug");
class GoogleIgnoreListConsumer {
constructor(map, normalizeSourceFn = normalizeSourcePath) {
this._sourceMap = map;
this._normalizeSource = normalizeSourceFn;
}
isIgnored({ source }) {
return source != null && this._getIgnoredSourceSet().has(source);
}
toArray(sources) {
const ignoredSourceSet = this._getIgnoredSourceSet();
const encoded = [];
for (const [sourceIndex, source] of sources.entries()) {
if (source != null && ignoredSourceSet.has(source)) {
encoded.push(sourceIndex);
}
}
return encoded;
}
_getIgnoredSourceSet() {
if (!this._ignoredSourceSet) {
const ignoredSourceSet = new Set();
this._buildIgnoredSourceSet(this._sourceMap, ignoredSourceSet);
this._ignoredSourceSet = ignoredSourceSet;
}
return this._ignoredSourceSet;
}
_buildIgnoredSourceSet(map, ignoredSourceSet) {
if (map.mappings === undefined) {
const indexMap = map;
indexMap.sections.forEach((section) =>
this._buildIgnoredSourceSet(section.map, ignoredSourceSet)
);
return;
}
if ("x_google_ignoreList" in map) {
const basicMap = map;
(basicMap.x_google_ignoreList || []).forEach((sourceIndex) => {
let source = basicMap.sources[sourceIndex];
if (source != null) {
source = this._normalizeSource(source, basicMap);
ignoredSourceSet.add(source);
}
});
}
}
}
module.exports = GoogleIgnoreListConsumer;

View File

@@ -0,0 +1,130 @@
"use strict";
const { normalizeSourcePath } = require("./source-map.debug");
const vlq = require("vlq");
const METADATA_FIELD_FUNCTIONS = 0;
class SourceMetadataMapConsumer {
constructor(map, normalizeSourceFn = normalizeSourcePath) {
this._sourceMap = map;
this._decodedFunctionMapCache = new Map();
this._normalizeSource = normalizeSourceFn;
}
functionNameFor({ line, column, source }) {
if (source && line != null && column != null) {
const mappings = this._getFunctionMappings(source);
if (mappings) {
const mapping = findEnclosingMapping(mappings, {
line,
column,
});
if (mapping) {
return mapping.name;
}
}
}
return null;
}
toArray(sources) {
const metadataBySource = this._getMetadataBySource();
const encoded = [];
for (const source of sources) {
encoded.push(metadataBySource[source] || null);
}
return encoded;
}
_getMetadataBySource() {
if (!this._metadataBySource) {
this._metadataBySource = this._getMetadataObjectsBySourceNames(
this._sourceMap
);
}
return this._metadataBySource;
}
_getFunctionMappings(source) {
if (this._decodedFunctionMapCache.has(source)) {
return this._decodedFunctionMapCache.get(source);
}
let parsedFunctionMap = null;
const metadataBySource = this._getMetadataBySource();
if (Object.prototype.hasOwnProperty.call(metadataBySource, source)) {
const metadata = metadataBySource[source] || [];
parsedFunctionMap = decodeFunctionMap(metadata[METADATA_FIELD_FUNCTIONS]);
}
this._decodedFunctionMapCache.set(source, parsedFunctionMap);
return parsedFunctionMap;
}
_getMetadataObjectsBySourceNames(map) {
if (map.mappings === undefined) {
const indexMap = map;
return Object.assign(
{},
...indexMap.sections.map((section) =>
this._getMetadataObjectsBySourceNames(section.map)
)
);
}
if ("x_facebook_sources" in map) {
const basicMap = map;
return (basicMap.x_facebook_sources || []).reduce(
(acc, metadata, index) => {
let source = basicMap.sources[index];
if (source != null) {
source = this._normalizeSource(source, basicMap);
acc[source] = metadata;
}
return acc;
},
{}
);
}
return {};
}
}
function decodeFunctionMap(functionMap) {
if (!functionMap) {
return [];
}
const parsed = [];
let line = 1;
let nameIndex = 0;
for (const lineMappings of functionMap.mappings.split(";")) {
let column = 0;
for (const mapping of lineMappings.split(",")) {
const [columnDelta, nameDelta, lineDelta = 0] = vlq.decode(mapping);
line += lineDelta;
nameIndex += nameDelta;
column += columnDelta;
parsed.push({
line,
column,
name: functionMap.names[nameIndex],
});
}
}
return parsed;
}
function findEnclosingMapping(mappings, target) {
let first = 0;
let it = 0;
let count = mappings.length;
let step;
while (count > 0) {
it = first;
step = Math.floor(count / 2);
it += step;
if (comparePositions(target, mappings[it]) >= 0) {
first = ++it;
count -= step + 1;
} else {
count = step;
}
}
return first ? mappings[first - 1] : null;
}
function comparePositions(a, b) {
if (a.line === b.line) {
return a.column - b.column;
}
return a.line - b.line;
}
module.exports = SourceMetadataMapConsumer;

View File

@@ -0,0 +1,589 @@
"use strict";
const { ChromeHeapSnapshotProcessor } = require("./ChromeHeapSnapshot");
const GoogleIgnoreListConsumer = require("./GoogleIgnoreListConsumer");
const SourceMetadataMapConsumer = require("./SourceMetadataMapConsumer");
const fs = require("fs");
const invariant = require("invariant");
const nullthrows = require("nullthrows");
const path = require("path");
const UNKNOWN_MODULE_IDS = {
segmentId: 0,
localId: undefined,
};
class SymbolicationContext {
constructor(options) {
this.options = {
inputLineStart: 1,
inputColumnStart: 0,
outputLineStart: 1,
outputColumnStart: 0,
nameSource: "function_names",
};
if (options) {
for (const option of [
"inputLineStart",
"inputColumnStart",
"outputLineStart",
"outputColumnStart",
]) {
if (options[option] != null) {
this.options[option] = options[option];
}
}
if (options.nameSource != null) {
this.options.nameSource = options.nameSource;
}
}
}
symbolicate(stackTrace) {
return stackTrace.replace(
/(?:([^@: \n(]+)(@|:))?(?:(?:([^@: \n(]+):)?(\d+):(\d+)|\[native code\])/g,
(match, func, delimiter, fileName, line, column) => {
if (delimiter === ":" && func && !fileName) {
fileName = func;
func = null;
}
const original = this.getOriginalPositionFor(
line,
column,
this.parseFileName(fileName || "")
);
return (
(original.source ?? "null") +
":" +
(original.line ?? "null") +
":" +
(original.name ?? "null")
);
}
);
}
symbolicateProfilerMap(mapFile) {
return fs
.readFileSync(mapFile, "utf8")
.split("\n")
.slice(0, -1)
.map((line) => {
const line_list = line.split(" ");
const trampoline = line_list[0];
const js_name = line_list[1];
const offset = parseInt(line_list[2], 10);
if (!offset) {
return trampoline + " " + trampoline;
}
const original = this.getOriginalPositionFor(
this.options.inputLineStart,
offset
);
return (
trampoline +
" " +
(original.name || js_name) +
"::" +
[original.source, original.line, original.column].join(":")
);
})
.join("\n");
}
symbolicateAttribution(obj) {
const loc = obj.location;
const line = loc.line != null ? loc.line : this.options.inputLineStart;
let column = Number(loc.column != null ? loc.column : loc.virtualOffset);
const file = loc.filename ? this.parseFileName(loc.filename) : null;
let original = this.getOriginalPositionFor(line, column, file);
const isBytecodeRange =
loc.bytecodeSize != null &&
loc.virtualOffset != null &&
loc.column == null;
const virtualOffset = Number(loc.virtualOffset);
const bytecodeSize = Number(loc.bytecodeSize);
while (
isBytecodeRange &&
original.source == null &&
++column < virtualOffset + bytecodeSize
) {
original = this.getOriginalPositionFor(line, column, file);
}
obj.location = {
file: original.source,
line: original.line,
column: original.column,
};
}
symbolicateChromeTrace(traceFile, { stdout, stderr }) {
const content = JSON.parse(fs.readFileSync(traceFile, "utf8"));
if (content.stackFrames == null) {
throw new Error("Unable to locate `stackFrames` section in trace.");
}
const keys = Object.keys(content.stackFrames);
stdout.write("Processing " + keys.length + " frames\n");
keys.forEach((key) => {
const entry = content.stackFrames[key];
let line;
let column;
let funcLine;
let funcColumn;
if (entry.funcVirtAddr != null && entry.offset != null) {
const funcVirtAddr = parseInt(entry.funcVirtAddr, 10);
const offsetInFunction = parseInt(entry.offset, 10);
line = this.options.inputLineStart;
column = funcVirtAddr + offsetInFunction;
funcLine = this.options.inputLineStart;
funcColumn = funcVirtAddr;
} else if (entry.line != null && entry.column != null) {
line = entry.line;
column = entry.column;
funcLine = entry.funcLine;
funcColumn = entry.funcColumn;
} else {
return;
}
const addressOriginal = this.getOriginalPositionDetailsFor(line, column);
let frameName;
if (addressOriginal.functionName) {
frameName = addressOriginal.functionName;
} else {
frameName = entry.name;
if (funcLine != null && funcColumn != null) {
const funcOriginal = this.getOriginalPositionFor(
funcLine,
funcColumn
);
if (funcOriginal.name != null) {
frameName = funcOriginal.name;
}
} else {
(stderr || stdout).write(
"Warning: no function prolog line/column info; name may be wrong\n"
);
}
}
entry.name = [
frameName,
"(",
[
addressOriginal.source ?? "null",
addressOriginal.line ?? "null",
addressOriginal.column ?? "null",
].join(":"),
")",
].join("");
});
stdout.write("Writing to " + traceFile + "\n");
fs.writeFileSync(traceFile, JSON.stringify(content));
}
getOriginalPositionFor(lineNumber, columnNumber, moduleIds) {
const position = this.getOriginalPositionDetailsFor(
lineNumber,
columnNumber,
moduleIds,
);
return {
start: position.start,
end: position.end,
lines: position.lines,
original_line: position.original_line,
token: position.token
};
}
symbolicateHermesMinidumpTrace(crashInfo) {
throw new Error("Not implemented");
}
symbolicateHeapSnapshot(snapshotContents) {
const snapshotData =
typeof snapshotContents === "string"
? JSON.parse(snapshotContents)
: snapshotContents;
const processor = new ChromeHeapSnapshotProcessor(snapshotData);
for (const frame of processor.traceFunctionInfos()) {
const moduleIds = this.parseFileName(frame.getString("script_name"));
const generatedLine = frame.getNumber("line");
const generatedColumn = frame.getNumber("column");
if (generatedLine === 0 && generatedColumn === 0) {
continue;
}
const {
line: originalLine,
column: originalColumn,
source: originalSource,
functionName: originalFunctionName,
} = this.getOriginalPositionDetailsFor(
frame.getNumber("line") - 1 + this.options.inputLineStart,
frame.getNumber("column") - 1 + this.options.inputColumnStart,
moduleIds
);
if (originalSource != null) {
frame.setString("script_name", originalSource);
if (originalLine != null) {
frame.setNumber(
"line",
originalLine - this.options.outputLineStart + 1
);
} else {
frame.setNumber("line", 0);
}
if (originalColumn != null) {
frame.setNumber(
"column",
originalColumn - this.options.outputColumnStart + 1
);
} else {
frame.setNumber("column", 0);
}
}
frame.setString("name", originalFunctionName ?? frame.getString("name"));
}
return snapshotData;
}
symbolicateHermesCoverageTrace(coverageInfo) {
const symbolicatedTrace = [];
const { executedFunctions } = coverageInfo;
if (executedFunctions != null) {
for (const stackItem of executedFunctions) {
const { line, column, SourceURL } = stackItem;
const generatedLine = line + this.options.inputLineStart;
const generatedColumn = column + this.options.inputColumnStart;
const originalPosition = this.getOriginalPositionDetailsFor(
generatedLine,
generatedColumn,
this.parseFileName(SourceURL || "")
);
symbolicatedTrace.push(originalPosition);
}
}
return symbolicatedTrace;
}
getOriginalPositionDetailsFor(lineNumber, columnNumber, moduleIds) {
throw new Error("Not implemented");
}
parseFileName(str) {
throw new Error("Not implemented");
}
}
class SingleMapSymbolicationContext extends SymbolicationContext {
constructor(SourceMapConsumer, sourceMapContent, options = {}) {
super(options);
this._SourceMapConsumer = SourceMapConsumer;
const sourceMapJson =
typeof sourceMapContent === "string"
? JSON.parse(sourceMapContent.replace(/^\)\]\}'/, ""))
: sourceMapContent;
const segments = {
0: this._initSegment(sourceMapJson),
};
if (sourceMapJson.x_facebook_segments) {
for (const key of Object.keys(sourceMapJson.x_facebook_segments)) {
const map = sourceMapJson.x_facebook_segments[key];
segments[key] = this._initSegment(map);
}
}
this._legacyFormat =
sourceMapJson.x_facebook_segments != null ||
sourceMapJson.x_facebook_offsets != null;
this._segments = segments;
}
_initSegment(map) {
const useFunctionNames = this.options.nameSource === "function_names";
const { _SourceMapConsumer: SourceMapConsumer } = this;
return {
get consumer() {
Object.defineProperty(this, "consumer", {
value: new SourceMapConsumer(map),
});
return this.consumer;
},
moduleOffsets: map.x_facebook_offsets || [],
get sourceFunctionsConsumer() {
Object.defineProperty(this, "sourceFunctionsConsumer", {
value: useFunctionNames ? new SourceMetadataMapConsumer(map) : null,
});
return this.sourceFunctionsConsumer;
},
get googleIgnoreListConsumer() {
Object.defineProperty(this, "googleIgnoreListConsumer", {
value: new GoogleIgnoreListConsumer(map),
});
return this.googleIgnoreListConsumer;
},
hermesOffsets: map.x_hermes_function_offsets,
};
}
symbolicateHermesMinidumpTrace(crashInfo) {
const symbolicatedTrace = [];
const { callstack } = crashInfo;
if (callstack != null) {
for (const stackItem of callstack) {
if (stackItem.NativeCode) {
symbolicatedTrace.push(stackItem);
} else {
const {
CJSModuleOffset,
SegmentID,
SourceURL,
FunctionID,
ByteCodeOffset: localOffset,
} = stackItem;
const cjsModuleOffsetOrSegmentID = nullthrows(
CJSModuleOffset ?? SegmentID,
"Either CJSModuleOffset or SegmentID must be specified in the Hermes stack frame"
);
const moduleInformation = this.parseFileName(SourceURL);
const generatedLine =
cjsModuleOffsetOrSegmentID + 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,
isIgnored: false,
});
} else {
const segmentOffsets =
hermesOffsets[Number(cjsModuleOffsetOrSegmentID)];
const generatedColumn =
segmentOffsets[FunctionID] +
localOffset +
this.options.inputColumnStart;
const originalPosition = this.getOriginalPositionDetailsFor(
generatedLine,
generatedColumn,
moduleInformation
);
symbolicatedTrace.push(originalPosition);
}
}
}
}
return symbolicatedTrace;
}
symbolicateHermesCoverageTrace(coverageInfo) {
const symbolicatedTrace = [];
const { executedFunctions } = coverageInfo;
if (executedFunctions != null) {
for (const stackItem of executedFunctions) {
const { line, column, SourceURL } = stackItem;
const generatedLine = line + this.options.inputLineStart;
const generatedColumn = column + this.options.inputColumnStart;
const originalPosition = this.getOriginalPositionDetailsFor(
generatedLine,
generatedColumn,
this.parseFileName(SourceURL || "")
);
symbolicatedTrace.push(originalPosition);
}
}
return symbolicatedTrace;
}
getOriginalPositionDetailsFor(lineNumber, columnNumber, moduleIds) {
lineNumber =
lineNumber != null
? lineNumber - this.options.inputLineStart + 1
: lineNumber;
columnNumber =
columnNumber != null
? columnNumber - this.options.inputColumnStart + 0
: columnNumber;
if (!moduleIds) {
moduleIds = UNKNOWN_MODULE_IDS;
}
let moduleLineOffset = 0;
const metadata = this._segments[moduleIds.segmentId + ""];
const { localId } = moduleIds;
if (localId != null) {
const { moduleOffsets } = metadata;
if (!moduleOffsets) {
throw new Error(
"Module ID given for a source map that does not have " +
"an x_facebook_offsets field"
);
}
if (moduleOffsets[localId] == null) {
throw new Error("Unknown module ID: " + localId);
}
moduleLineOffset = moduleOffsets[localId];
}
const original = metadata.consumer.originalPositionFor({
line: Number(lineNumber) + moduleLineOffset,
column: Number(columnNumber),
});
const sourceContent = metadata.consumer.sourceContentFor(original.source);
const lines = sourceContent.split('\n');
// Get the original line number (subtract 1 to convert to zero-indexed)
const originalLine = original.line - 1;
// Determine start and end bounds ensuring they do not go out of the array
const startLine = Math.max(originalLine - 10, 0); // Ensure it doesn't go below 0
const endLine = Math.min(originalLine + 10, lines.length - 1); // Ensure it doesn't exceed the total number of lines
// Extract the 10 lines before, original line, and 10 lines after
const surroundingLines = lines.slice(startLine, endLine + 1);
// console.log("error happened in", lines[originalLine])
// if (metadata.sourceFunctionsConsumer) {
// original.functionName =
// metadata.sourceFunctionsConsumer.functionNameFor(original) || null;
// } else {
// original.functionName = null;
// }
//console.log(surroundingLines)
original.isIgnored = metadata.googleIgnoreListConsumer.isIgnored(original);
return {
...original,
original_line: original.line - 1 + this.options.outputLineStart,
lines: surroundingLines,
token: original.source,
start: startLine,
end: endLine
};
}
/*
token: token.to_string(),
original_line,
lines: vec_of_str(&context_lines),
start: start,
end: end
*/
parseFileName(str) {
if (this._legacyFormat) {
return parseSingleMapFileName(str);
}
return UNKNOWN_MODULE_IDS;
}
}
class DirectorySymbolicationContext extends SymbolicationContext {
constructor(SourceMapConsumer, rootDir, options = {}) {
super(options);
this._fileMaps = new Map();
this._rootDir = rootDir;
this._SourceMapConsumer = SourceMapConsumer;
}
_loadMap(mapFilename) {
invariant(
fs.existsSync(mapFilename),
`Could not read source map from '${mapFilename}'`
);
let fileMap = this._fileMaps.get(mapFilename);
if (fileMap == null) {
fileMap = new SingleMapSymbolicationContext(
this._SourceMapConsumer,
fs.readFileSync(mapFilename, "utf8"),
this.options
);
this._fileMaps.set(mapFilename, fileMap);
}
return fileMap;
}
getOriginalPositionDetailsFor(lineNumber, columnNumber, filename) {
invariant(
filename != null,
"filename is required for DirectorySymbolicationContext"
);
let mapFilename;
const relativeFilename = path.relative(
this._rootDir,
path.resolve(this._rootDir, filename)
);
if (!relativeFilename.startsWith("..")) {
mapFilename = path.join(this._rootDir, relativeFilename + ".map");
}
if (mapFilename == null || !fs.existsSync(mapFilename)) {
lineNumber =
lineNumber != null
? lineNumber -
this.options.inputLineStart +
this.options.outputLineStart
: lineNumber;
columnNumber =
columnNumber != null
? columnNumber -
this.options.inputColumnStart +
this.options.outputColumnStart
: columnNumber;
return {
line: lineNumber,
column: columnNumber,
source: filename,
name: null,
functionName: null,
isIgnored: false,
};
}
return this._loadMap(mapFilename).getOriginalPositionDetailsFor(
lineNumber,
columnNumber
);
}
parseFileName(str) {
return str;
}
}
function parseSingleMapFileName(str) {
const modMatch = str.match(/^(\d+).js$/);
if (modMatch != null) {
return {
segmentId: 0,
localId: Number(modMatch[1]),
};
}
const segMatch = str.match(/^seg-(\d+)(?:_(\d+))?.js$/);
if (segMatch != null) {
return {
segmentId: Number(segMatch[1]),
localId: segMatch[2] ? Number(segMatch[2]) : null,
};
}
return UNKNOWN_MODULE_IDS;
}
function createContext(SourceMapConsumer, sourceMapContent, options = {}) {
return new SingleMapSymbolicationContext(
SourceMapConsumer,
sourceMapContent,
options
);
}
function unstable_createDirectoryContext(
SourceMapConsumer,
rootDir,
options = {}
) {
return new DirectorySymbolicationContext(SourceMapConsumer, rootDir, options);
}
function getOriginalPositionFor(lineNumber, columnNumber, moduleIds, context) {
return context.getOriginalPositionFor(lineNumber, columnNumber, moduleIds);
}
function symbolicate(stackTrace, context) {
return context.symbolicate(stackTrace);
}
function symbolicateProfilerMap(mapFile, context) {
return context.symbolicateProfilerMap(mapFile);
}
function symbolicateAttribution(obj, context) {
context.symbolicateAttribution(obj);
}
function symbolicateChromeTrace(traceFile, { stdout, stderr }, context) {
return context.symbolicateChromeTrace(traceFile, {
stdout,
stderr,
});
}
module.exports = {
createContext,
unstable_createDirectoryContext,
getOriginalPositionFor,
parseFileName: parseSingleMapFileName,
symbolicate,
symbolicateProfilerMap,
symbolicateAttribution,
symbolicateChromeTrace,
//SourceMetadataMapConsumer,
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,33 @@
"use strict";
const Symbolication = require("./Symbolication.js");
const {SourceMapConsumer} = require('./source-map.debug');
const fs = require("fs");
const read = (fileName) => fs.readFileSync(fileName, "utf8");
try {
const frames = JSON.parse(process.argv[2])//{"frames":[{"filename":"app:///index.android.bundle","function":"callFunctionReturnFlushedQueue","in_app":true,"lineno":1,"colno":177331,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"__guard","in_app":true,"lineno":1,"colno":178310,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"anonymous","in_app":true,"lineno":1,"colno":177373,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"__callFunction","in_app":true,"lineno":1,"colno":178820,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"receiveTouches","in_app":true,"lineno":1,"colno":160610,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"_receiveRootNodeIDEvent","in_app":true,"lineno":1,"colno":107803,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"batchedUpdates","in_app":true,"lineno":1,"colno":107530,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"batchedUpdatesImpl","in_app":true,"lineno":1,"colno":165717,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"flushSyncCallbacks","in_app":true,"lineno":1,"colno":114645,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"performSyncWorkOnRoot","in_app":true,"lineno":1,"colno":149365,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"renderRootSync","in_app":true,"lineno":1,"colno":151872,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"workLoopSync","in_app":true,"lineno":1,"colno":151988,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"performUnitOfWork","in_app":true,"lineno":1,"colno":152085,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"beginWork$1","in_app":true,"lineno":1,"colno":165344,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"renderWithHooks","in_app":true,"lineno":1,"colno":124679,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"},{"filename":"app:///index.android.bundle","function":"Profile","in_app":true,"lineno":1,"colno":2426339,"source_map_path":"source-map-cache/123/2.12.14/index.android.bundle.map"}]}
if (!frames) {
throw new Error("please pass frames as first argument");
}
const processedFrame = [];
frames.frames.forEach(frame => {
const MAP_FILE_PATH = `${frame.source_map_path}`;
const map = read(MAP_FILE_PATH);
const context = Symbolication.createContext(SourceMapConsumer, map);
processedFrame.push(Symbolication.getOriginalPositionFor(frame.lineno, frame.colno, Symbolication.parseFileName(frame.filename), context));
})
console.log(JSON.stringify({
symbolicated_frames: processedFrame
}))
}
catch (err) {
console.log('payload', process.argv[2]);
console.error(err.message);
process.exit(1);
}

View File

@@ -0,0 +1,402 @@
{
"name": "cybertron-symboicator-react-native",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cybertron-symboicator-react-native",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"invariant": "^2.2.4",
"metro-source-map": "^0.81.0",
"nullthrows": "^1.1.1",
"vlq": "^2.0.4"
}
},
"node_modules/@babel/code-frame": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
"dependencies": {
"@babel/helper-validator-identifier": "^7.25.9",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/generator": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz",
"integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==",
"dependencies": {
"@babel/parser": "^7.26.2",
"@babel/types": "^7.26.0",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
"integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
"dependencies": {
"@babel/types": "^7.26.0"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/template": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
"integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
"dependencies": {
"@babel/code-frame": "^7.25.9",
"@babel/parser": "^7.25.9",
"@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
"integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
"dependencies": {
"@babel/code-frame": "^7.25.9",
"@babel/generator": "^7.25.9",
"@babel/parser": "^7.25.9",
"@babel/template": "^7.25.9",
"@babel/types": "^7.25.9",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse--for-generate-function-map": {
"name": "@babel/traverse",
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
"integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
"dependencies": {
"@babel/code-frame": "^7.25.9",
"@babel/generator": "^7.25.9",
"@babel/parser": "^7.25.9",
"@babel/template": "^7.25.9",
"@babel/types": "^7.25.9",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/types": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
"integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"node_modules/debug": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/flow-enums-runtime": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz",
"integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="
},
"node_modules/globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"engines": {
"node": ">=4"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"node_modules/jsesc": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
"integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"bin": {
"jsesc": "bin/jsesc"
},
"engines": {
"node": ">=6"
}
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/metro-source-map": {
"version": "0.81.0",
"resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.0.tgz",
"integrity": "sha512-TzsVxhH83dyxg4A4+L1nzNO12I7ps5IHLjKGZH3Hrf549eiZivkdjYiq/S5lOB+p2HiQ+Ykcwtmcja95LIC62g==",
"dependencies": {
"@babel/traverse": "^7.25.3",
"@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3",
"@babel/types": "^7.25.2",
"flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4",
"metro-symbolicate": "0.81.0",
"nullthrows": "^1.1.1",
"ob1": "0.81.0",
"source-map": "^0.5.6",
"vlq": "^1.0.0"
},
"engines": {
"node": ">=18.18"
}
},
"node_modules/metro-source-map/node_modules/vlq": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="
},
"node_modules/metro-symbolicate": {
"version": "0.81.0",
"resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.0.tgz",
"integrity": "sha512-C/1rWbNTPYp6yzID8IPuQPpVGzJ2rbWYBATxlvQ9dfK5lVNoxcwz77hjcY8ISLsRRR15hyd/zbjCNKPKeNgE1Q==",
"dependencies": {
"flow-enums-runtime": "^0.0.6",
"invariant": "^2.2.4",
"metro-source-map": "0.81.0",
"nullthrows": "^1.1.1",
"source-map": "^0.5.6",
"through2": "^2.0.1",
"vlq": "^1.0.0"
},
"bin": {
"metro-symbolicate": "src/index.js"
},
"engines": {
"node": ">=18.18"
}
},
"node_modules/metro-symbolicate/node_modules/vlq": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/nullthrows": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
"integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="
},
"node_modules/ob1": {
"version": "0.81.0",
"resolved": "https://registry.npmjs.org/ob1/-/ob1-0.81.0.tgz",
"integrity": "sha512-6Cvrkxt1tqaRdWqTAMcVYEiO5i1xcF9y7t06nFdjFqkfPsEloCf8WwhXdwBpNUkVYSQlSGS7cDgVQR86miBfBQ==",
"dependencies": {
"flow-enums-runtime": "^0.0.6"
},
"engines": {
"node": ">=18.18"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"dependencies": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/vlq": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz",
"integrity": "sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA=="
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"engines": {
"node": ">=0.4"
}
}
}
}

View File

@@ -0,0 +1,12 @@
{
"name": "cybertron-symboicator-react-native",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"invariant": "^2.2.4",
"metro-source-map": "^0.81.0",
"nullthrows": "^1.1.1",
"vlq": "^2.0.4"
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,209 @@
"use strict";
const Symbolication = require("./Symbolication.js");
const fs = require("fs");
const SourceMapConsumer = require("source-map").SourceMapConsumer;
const through2 = require("through2");
function printHelp() {
const usages = [
"Usage: " + __filename + " <source-map-file>",
" " + __filename + " <source-map-file> <line> [column]",
" " + __filename + " <source-map-file> <moduleId>.js <line> [column]",
" " + __filename + " <source-map-file> <mapfile>.profmap",
" " +
__filename +
" <source-map-file> --attribution < in.jsonl > out.jsonl",
" " + __filename + " <source-map-file> <tracefile>.cpuprofile",
" Optional flags:",
" --no-function-names",
" --hermes-crash (mutually exclusive with --hermes-coverage)",
" --hermes-coverage (mutually exclusive with --hermes-crash)",
" --input-line-start <line> (default: 1)",
" --input-column-start <column> (default: 0)",
" --output-line-start <line> (default: 1)",
" --output-column-start <column> (default: 0)",
];
console.error(usages.join("\n"));
}
async function main(
argvInput = process.argv.slice(2),
{ stdin, stderr, stdout } = process
) {
const argv = argvInput.slice();
function checkAndRemoveArg(arg, valuesPerArg = 0) {
let values = null;
for (let idx = argv.indexOf(arg); idx !== -1; idx = argv.indexOf(arg)) {
argv.splice(idx, 1);
values = values || [];
values.push(argv.splice(idx, valuesPerArg));
}
return values;
}
function checkAndRemoveArgWithValue(arg) {
const values = checkAndRemoveArg(arg, 1);
return values ? values[0][0] : null;
}
try {
const noFunctionNames = checkAndRemoveArg("--no-function-names");
const isHermesCrash = checkAndRemoveArg("--hermes-crash");
const isCoverage = checkAndRemoveArg("--hermes-coverage");
const inputLineStart = Number.parseInt(
checkAndRemoveArgWithValue("--input-line-start") || "1",
10
);
const inputColumnStart = Number.parseInt(
checkAndRemoveArgWithValue("--input-column-start") || "0",
10
);
const outputLineStart = Number.parseInt(
checkAndRemoveArgWithValue("--output-line-start") || "1",
10
);
const outputColumnStart = Number.parseInt(
checkAndRemoveArgWithValue("--output-column-start") || "0",
10
);
if (argv.length < 1 || argv.length > 4) {
printHelp();
return 1;
}
if (isHermesCrash && isCoverage) {
console.error(
"Pass either --hermes-crash or --hermes-coverage, not both"
);
printHelp();
return 1;
}
const sourceMapFileName = argv.shift();
const options = {
nameSource: noFunctionNames ? "identifier_names" : "function_names",
inputLineStart,
inputColumnStart,
outputLineStart,
outputColumnStart,
};
let context;
if (fs.lstatSync(sourceMapFileName).isDirectory()) {
context = Symbolication.unstable_createDirectoryContext(
SourceMapConsumer,
sourceMapFileName,
options
);
} else {
const content = fs.readFileSync(sourceMapFileName, "utf8");
context = Symbolication.createContext(
SourceMapConsumer,
content,
options
);
}
if (argv.length === 0) {
const stackTrace = await readAll(stdin);
if (isHermesCrash) {
const stackTraceJSON = JSON.parse(stackTrace);
const symbolicatedTrace =
context.symbolicateHermesMinidumpTrace(stackTraceJSON);
stdout.write(JSON.stringify(symbolicatedTrace));
} else if (isCoverage) {
const stackTraceJSON = JSON.parse(stackTrace);
const symbolicatedTrace =
context.symbolicateHermesCoverageTrace(stackTraceJSON);
stdout.write(JSON.stringify(symbolicatedTrace));
} else {
stdout.write(context.symbolicate(stackTrace));
}
} else if (argv[0].endsWith(".profmap")) {
stdout.write(context.symbolicateProfilerMap(argv[0]));
} else if (
argv[0].endsWith(".heapsnapshot") ||
argv[0].endsWith(".heaptimeline")
) {
stdout.write(
JSON.stringify(
context.symbolicateHeapSnapshot(fs.readFileSync(argv[0], "utf8"))
)
);
} else if (argv[0] === "--attribution") {
let buffer = "";
await waitForStream(
stdin
.pipe(
through2(function (data, enc, callback) {
buffer += data;
const lines = buffer.split("\n");
for (let i = 0, e = lines.length - 1; i < e; i++) {
this.push(lines[i]);
}
buffer = lines[lines.length - 1];
callback();
})
)
.pipe(
through2.obj(function (data, enc, callback) {
const obj = JSON.parse(data);
context.symbolicateAttribution(obj);
this.push(JSON.stringify(obj) + "\n");
callback();
})
)
.pipe(stdout)
);
} else if (argv[0].endsWith(".cpuprofile")) {
context.symbolicateChromeTrace(argv[0], {
stdout,
stderr,
});
} else {
let moduleIds;
if (argv[0].endsWith(".js")) {
moduleIds = context.parseFileName(argv[0]);
argv.shift();
} else {
moduleIds = null;
}
const lineNumber = argv.shift();
const columnNumber = argv.shift() || 0;
const original = context.getOriginalPositionFor(
+lineNumber,
+columnNumber,
moduleIds
);
stdout.write(
[
original.source ?? "null",
original.line ?? "null",
original.name ?? "null",
].join(":") + "\n"
);
}
} catch (error) {
stderr.write(error + "\n");
return 1;
}
return 0;
}
function readAll(stream) {
return new Promise((resolve) => {
let data = "";
if (stream.isTTY === true) {
resolve(data);
return;
}
stream.setEncoding("utf8");
stream.on("readable", () => {
let chunk;
while ((chunk = stream.read())) {
data += chunk.toString();
}
});
stream.on("end", () => {
resolve(data);
});
});
}
function waitForStream(stream) {
return new Promise((resolve) => {
stream.on("finish", resolve);
});
}
module.exports = main;

View File

@@ -0,0 +1,285 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@babel/code-frame@^7.25.9":
version "7.26.2"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz"
integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
dependencies:
"@babel/helper-validator-identifier" "^7.25.9"
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/generator@^7.25.9":
version "7.26.2"
resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz"
integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==
dependencies:
"@babel/parser" "^7.26.2"
"@babel/types" "^7.26.0"
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.25"
jsesc "^3.0.2"
"@babel/helper-string-parser@^7.25.9":
version "7.25.9"
resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz"
integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
"@babel/helper-validator-identifier@^7.25.9":
version "7.25.9"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz"
integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
"@babel/parser@^7.25.9", "@babel/parser@^7.26.2":
version "7.26.2"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz"
integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==
dependencies:
"@babel/types" "^7.26.0"
"@babel/template@^7.25.9":
version "7.25.9"
resolved "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz"
integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==
dependencies:
"@babel/code-frame" "^7.25.9"
"@babel/parser" "^7.25.9"
"@babel/types" "^7.25.9"
"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3":
version "7.25.9"
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz"
integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
dependencies:
"@babel/code-frame" "^7.25.9"
"@babel/generator" "^7.25.9"
"@babel/parser" "^7.25.9"
"@babel/template" "^7.25.9"
"@babel/types" "^7.25.9"
debug "^4.3.1"
globals "^11.1.0"
"@babel/traverse@^7.25.3":
version "7.25.9"
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz"
integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==
dependencies:
"@babel/code-frame" "^7.25.9"
"@babel/generator" "^7.25.9"
"@babel/parser" "^7.25.9"
"@babel/template" "^7.25.9"
"@babel/types" "^7.25.9"
debug "^4.3.1"
globals "^11.1.0"
"@babel/types@^7.25.2", "@babel/types@^7.25.9", "@babel/types@^7.26.0":
version "7.26.0"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz"
integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==
dependencies:
"@babel/helper-string-parser" "^7.25.9"
"@babel/helper-validator-identifier" "^7.25.9"
"@jridgewell/gen-mapping@^0.3.5":
version "0.3.5"
resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz"
integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==
dependencies:
"@jridgewell/set-array" "^1.2.1"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping" "^0.3.24"
"@jridgewell/resolve-uri@^3.1.0":
version "3.1.2"
resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz"
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
"@jridgewell/set-array@^1.2.1":
version "1.2.1"
resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz"
integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
version "1.5.0"
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz"
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
version "0.3.25"
resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz"
integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
dependencies:
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
debug@^4.3.1:
version "4.3.7"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz"
integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
dependencies:
ms "^2.1.3"
flow-enums-runtime@^0.0.6:
version "0.0.6"
resolved "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz"
integrity sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
dependencies:
loose-envify "^1.0.0"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
jsesc@^3.0.2:
version "3.0.2"
resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz"
integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
loose-envify@^1.0.0:
version "1.4.0"
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
metro-source-map@^0.81.0, metro-source-map@0.81.0:
version "0.81.0"
resolved "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.81.0.tgz"
integrity sha512-TzsVxhH83dyxg4A4+L1nzNO12I7ps5IHLjKGZH3Hrf549eiZivkdjYiq/S5lOB+p2HiQ+Ykcwtmcja95LIC62g==
dependencies:
"@babel/traverse" "^7.25.3"
"@babel/traverse--for-generate-function-map" "npm:@babel/traverse@^7.25.3"
"@babel/types" "^7.25.2"
flow-enums-runtime "^0.0.6"
invariant "^2.2.4"
metro-symbolicate "0.81.0"
nullthrows "^1.1.1"
ob1 "0.81.0"
source-map "^0.5.6"
vlq "^1.0.0"
metro-symbolicate@0.81.0:
version "0.81.0"
resolved "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.81.0.tgz"
integrity sha512-C/1rWbNTPYp6yzID8IPuQPpVGzJ2rbWYBATxlvQ9dfK5lVNoxcwz77hjcY8ISLsRRR15hyd/zbjCNKPKeNgE1Q==
dependencies:
flow-enums-runtime "^0.0.6"
invariant "^2.2.4"
metro-source-map "0.81.0"
nullthrows "^1.1.1"
source-map "^0.5.6"
through2 "^2.0.1"
vlq "^1.0.0"
ms@^2.1.3:
version "2.1.3"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
nullthrows@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz"
integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==
ob1@0.81.0:
version "0.81.0"
resolved "https://registry.npmjs.org/ob1/-/ob1-0.81.0.tgz"
integrity sha512-6Cvrkxt1tqaRdWqTAMcVYEiO5i1xcF9y7t06nFdjFqkfPsEloCf8WwhXdwBpNUkVYSQlSGS7cDgVQR86miBfBQ==
dependencies:
flow-enums-runtime "^0.0.6"
picocolors@^1.0.0:
version "1.1.1"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
readable-stream@~2.3.6:
version "2.3.8"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
dependencies:
safe-buffer "~5.1.0"
through2@^2.0.1:
version "2.0.5"
resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz"
integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
dependencies:
readable-stream "~2.3.6"
xtend "~4.0.1"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
vlq@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz"
integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==
vlq@^2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/vlq/-/vlq-2.0.4.tgz"
integrity sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==
xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==

View File

@@ -42,6 +42,9 @@ func SymbolicatorClient(cmdArg *Command) (SymbolicatedStackTrace, error) {
}
// Get the output
output := out.String()
println(output)
println(err)
symbolicatedStackTrace := SymbolicatedStackTrace{}
jsonParseError := json.Unmarshal([]byte(output), &symbolicatedStackTrace)
return symbolicatedStackTrace, jsonParseError

View File

@@ -8,4 +8,6 @@ while read -r line; do
echo "Building log-enricher locally"
eval "make build-log-enricher
echo "installing node modules"
cd bins/cybertron-symbolicator-react-native && npm install && cd ../../
$ENVS out/log-enricher"

View File

@@ -85,12 +85,20 @@ func extractFilename(url string) string {
return filename + ".map"
}
func extractPlatform(url string) string {
if strings.HasPrefix(url, "app:///") {
return "REACT_NATIVE"
}
return "WEB"
}
func (ep *ErrorProcessor) ProcessError(error []byte) {
ep.logger.Info("processing error in consumer")
var payload Exception
err := json.Unmarshal(error, &payload)
var validFrames []Frame
var invalidFrames []Frame
var platform = extractPlatform(payload.Stacktrace.Frames[0].Filename)
if err != nil {
ep.logger.Error("error in unmarshalling exception", zap.Error(err))
@@ -122,10 +130,24 @@ func (ep *ErrorProcessor) ProcessError(error []byte) {
}
payload.Stacktrace.Frames = validFrames
var frames, _ = json.Marshal(&payload.Stacktrace)
var frames, marshalErr = json.Marshal(&payload.Stacktrace)
if marshalErr != nil {
ep.logger.Error("unable to serilize frames", zap.Error(marshalErr))
}
var symbolicatorCommand = ""
var args = []string{""}
if platform == "REACT_NATIVE" {
symbolicatorCommand = "node"
args = []string{"bins/cybertron-symbolicator-react-native/index.js", string(frames)}
} else {
symbolicatorCommand = "bins/source-map"
args = []string{string(frames)}
}
command := &symbolicator.Command{
Cmd: "bins/source-map",
Args: []string{string(frames)},
Cmd: symbolicatorCommand,
Args: args,
}
output, err := symbolicator.SymbolicatorClient(command)