Skip to content

Commit

Permalink
add support for parsing Sentry JSON dumps
Browse files Browse the repository at this point in the history
  • Loading branch information
nornagon committed Oct 3, 2019
1 parent be738c1 commit bcd7bce
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 10 deletions.
48 changes: 39 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,7 @@ const groupBy = (xs, f) => {
}

const parseAddresses = (content) => {
const addresses = []
content.split('\n').forEach((line, i) => {
const a = parseAddress(line)
if (a) {
addresses.push({...a, i})
}
})
const addresses = parseAsSentryDump(content) || parseAsLines(content)
return groupBy(addresses, a => `${a.library};${a.image}`).map(as => {
const {library, image} = as[0]
return library == null
Expand All @@ -114,9 +108,45 @@ const parseAddresses = (content) => {
}

const parseAddress = (line) => {
const parser = /\(in [^)]+\)/.test(line) ? parseSamplingAddress : parseStackTraceAddress
return parser(line)
if (/\(in [^)]+\)/.test(line)) {
return parseSamplingAddress(line)
} else if (/frame #/.test(line)) {
return parseDebuggerAddress(line)
} else {
return parseStackTraceAddress(line)
}
}

const parseAsLines = (content) => {
const addresses = []
content.split('\n').forEach((line, i) => {
const a = parseAddress(line)
if (a) {
addresses.push({...a, i})
}
})
return addresses
}

const parseAsSentryDump = (content) => {
try {
const json = JSON.parse(content)
if (json.debug_meta == null || json.exception == null)
return
return json.exception.values[0].stacktrace.frames.map(frame => {
const libraryFileName = path.basename(frame.package)
const library = libraryFileName === 'Electron Framework'
? 'com.github.electron.framework' : libraryFileName
const address = frame.instruction_addr
const imageData = json.debug_meta.images.find(image => image.code_file === frame.package)
const image = imageData ? imageData.image_addr : null
return {library, address, image}
}).reverse() // Sentry puts the bottom of the stack at the beginning of the array
} catch (e) {
// Not JSON. Thus not a Sentry dump.
}
}

module.exports.testing = {parseAddress, parseAddresses}

// Lines from stack traces are of the format:
Expand Down
93 changes: 92 additions & 1 deletion spec/parsing.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {parseAddress} = require('..').testing
const {parseAddress, parseAddresses} = require('..').testing

describe('sampling address parsing', () => {
it('passes through an already-symbolicated address', () => {
Expand All @@ -23,3 +23,94 @@ describe('sampling address parsing', () => {
.toEqual({library: 'libnode.dylib', address: '0x104f97014', image: '0x104f80000'})
})
})

describe('sentry dump parsing', () => {
it('parses a sentry dump', () => {
const addresses = parseAddresses(`{
"debug_meta": {
"images": [{
"code_file": "/Applications/Somiibo.app/Contents/Frameworks/Somiibo Helper (Renderer).app/Contents/MacOS/Somiibo Helper (Renderer)",
"image_addr": "0x1096d1000",
"debug_file": "Somiibo Helper (Renderer)",
"image_size": 237568,
"type": "macho",
"debug_id": "49c385a1-0c31-33bb-9742-3795d0bcf293"
}, {
"code_file": "/Applications/Somiibo.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework",
"image_addr": "0x109719000",
"debug_file": "Electron Framework",
"image_size": 106332160,
"type": "macho",
"debug_id": "ef0079c1-ff8e-3e51-9bf0-eba220c7f894"
}]
},
"exception": {
"values": [{
"stacktrace": {
"frames": [{
"trust": "scan",
"in_app": false,
"data": {
"orig_in_app": -1,
"symbolicator_status": "missing"
},
"instruction_addr": "0x7fff6b6173d5",
"package": "/usr/lib/system/libdyld.dylib"
}, {
"trust": "fp",
"in_app": true,
"data": {
"orig_in_app": -1,
"symbolicator_status": "missing"
},
"instruction_addr": "0x1096d2705",
"package": "/Applications/Somiibo.app/Contents/Frameworks/Somiibo Helper (Renderer).app/Contents/MacOS/Somiibo Helper (Renderer)"
}, {
"trust": "fp",
"in_app": true,
"data": {
"orig_in_app": -1,
"symbolicator_status": "missing"
},
"instruction_addr": "0x10971bb54",
"package": "/Applications/Somiibo.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework"
}, {
"trust": "fp",
"in_app": true,
"data": {
"orig_in_app": -1,
"symbolicator_status": "missing"
},
"instruction_addr": "0x10a0de754",
"package": "/Applications/Somiibo.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework"
}]
}
}]
}
}`)
expect(addresses).toEqual([
{
addresses: [
{ address: "0x10a0de754", image: "0x109719000", library: "com.github.electron.framework" },
{ address: "0x10971bb54", image: "0x109719000", library: "com.github.electron.framework" }
],
image: "0x109719000",
library: "com.github.electron.framework"
},
{
addresses: [
{ address: "0x1096d2705", image: "0x1096d1000", library: "Somiibo Helper (Renderer)" }
],
image: "0x1096d1000",
library: "Somiibo Helper (Renderer)"
},
{
addresses: [
{ address: "0x7fff6b6173d5", image: null, library: "libdyld.dylib" }
],
image: null,
library: "libdyld.dylib"
}
])
})
})

0 comments on commit bcd7bce

Please sign in to comment.