-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 73c0ab3
Showing
11 changed files
with
222 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cache | ||
node_modules |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cache | ||
test |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# electron-atos | ||
|
||
Symbolicate an [Electron](http://electron.atom.io) macOS crash report that is | ||
missing symbols. | ||
|
||
## Usage | ||
|
||
- Copy the lines missing symbols from a crash report to a local `crash.txt` file: | ||
|
||
``` | ||
0 com.github.electron.framework 0x000000010d01fad3 0x10c497000 + 12094163 | ||
1 com.github.electron.framework 0x000000010d095014 0x10c497000 + 12574740 | ||
``` | ||
|
||
- Run `electron-atos` and specify the path to the file and the version of | ||
Electron that was being used. | ||
|
||
```sh | ||
electron-atos --file /path/to/crash.txt --version 1.4.14 | ||
``` | ||
|
||
- The symbols of the given address will be printed out: | ||
|
||
``` | ||
content::RenderProcessHostImpl::Cleanup() (in Electron Framework) (render_process_host_impl.cc:1908) | ||
content::ServiceWorkerProcessManager::Shutdown() (in Electron Framework) (__tree:165) | ||
``` |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/usr/bin/env node | ||
|
||
const {argv} = require('yargs') | ||
const atos = require('./index') | ||
|
||
atos(argv, (error, symbols) => { | ||
if (error != null) { | ||
console.error(error.stack || error.message) | ||
process.exit(1) | ||
} else { | ||
console.log(symbols.join('\n')) | ||
} | ||
}) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
const ChildProcess = require('child_process') | ||
const electronDownload = require('electron-download') | ||
const extractZip = require('extract-zip') | ||
const fs = require('fs') | ||
const path = require('path') | ||
|
||
module.exports = (options, callback) => { | ||
const {version, quiet, file, force} = options | ||
const directory = path.join(__dirname, 'cache', version) | ||
|
||
const addresses = getAddresses(file) | ||
|
||
download({version, quiet, directory, force}, (error) => { | ||
if (error != null) return callback(error) | ||
|
||
const symbols = [] | ||
const symbolicateNextAddress = () => { | ||
const address = addresses.shift() | ||
if (address == null) return callback(null, symbols) | ||
symbolicate({directory, address}, (error, symbol) => { | ||
if (error != null) return callback(error) | ||
symbols.push(symbol) | ||
symbolicateNextAddress() | ||
}) | ||
} | ||
symbolicateNextAddress() | ||
}) | ||
} | ||
|
||
const download = (options, callback) => { | ||
const {version, quiet, directory, force} = options | ||
|
||
if (fs.existsSync(directory) && !force) return callback() | ||
|
||
electronDownload({ | ||
version: version, | ||
dsym: true, | ||
platform: 'darwin', | ||
arch: 'x64', | ||
quiet: quiet, | ||
force: force | ||
}, (error, zipPath) => { | ||
if (error != null) return callback(error) | ||
extractZip(zipPath, {dir: directory}, callback) | ||
}) | ||
} | ||
|
||
const symbolicate = (options, callback) => { | ||
const {directory, address} = options | ||
|
||
const command = 'atos' | ||
const args = [ | ||
'-o', | ||
getLibraryPath(directory, address.library), | ||
'-l', | ||
address.image | ||
] | ||
const atos = ChildProcess.spawn(command, args) | ||
let output = '' | ||
let error = '' | ||
atos.on('close', (code) => { | ||
if (code === 0) { | ||
callback(null, output.trim()) | ||
} else { | ||
error = `atos exited with ${code}: ${error}` | ||
callback(new Error(error)) | ||
} | ||
}) | ||
atos.stdout.on('data', (data) => { | ||
output += data.toString() | ||
}) | ||
atos.stderr.on('data', (data) => { | ||
error += data.toString() | ||
}) | ||
atos.stdin.write(address.address) | ||
atos.stdin.end() | ||
} | ||
|
||
const getAddresses = (file) => { | ||
const content = fs.readFileSync(file, 'utf8') | ||
const addresses = [] | ||
content.split('\n').forEach((line) => { | ||
const segments = line.split(/\s+/) | ||
const index = parseInt(segments[0]) | ||
if (!isFinite(index)) return | ||
|
||
const library = segments[1] | ||
const address = segments[2] | ||
const image = segments[3] | ||
addresses.push({library, image, address}) | ||
}) | ||
return addresses | ||
} | ||
|
||
const getLibraryPath = (rootDirectory, library) => { | ||
switch (library) { | ||
case 'com.github.electron.framework': | ||
return path.join(rootDirectory, 'Electron framework.framework.dSYM', 'Contents', 'Resources', 'DWARF', 'Electron Framework') | ||
case 'libnode.dylib': | ||
return path.join(rootDirectory, 'libnode.dylib.dSYM', 'Contents', 'Resources', 'DWARF', 'libnode.dylib') | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "electron-atos", | ||
"version": "1.0.0", | ||
"description": "Symbolicate Electron macOS crashes", | ||
"main": "index.js", | ||
"bin": { | ||
"electron-atos": "./cli.js" | ||
}, | ||
"scripts": { | ||
"test": "mocha test" | ||
}, | ||
"keywords": [ | ||
"atos", | ||
"electron" | ||
], | ||
"author": "Kevin Sawicki", | ||
"license": "ISC", | ||
"dependencies": { | ||
"extract-zip": "^1.6.0", | ||
"yargs": "^6.6.0" | ||
}, | ||
"os": [ | ||
"darwin" | ||
], | ||
"engines": { | ||
"node": ">=7" | ||
}, | ||
"devDependencies": { | ||
"mocha": "^3.2.0", | ||
"standard": "^8.6.0" | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
0 com.github.electron.framework 0x000000010d01fad3 0x10c497000 + 12094163 | ||
1 com.github.electron.framework 0x000000010d095014 0x10c497000 + 12574740 |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
content::RenderProcessHostImpl::Cleanup() (in Electron Framework) (render_process_host_impl.cc:1908) | ||
content::ServiceWorkerProcessManager::Shutdown() (in Electron Framework) (__tree:165) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
3 libnode.dylib 0x000000010ab5c383 0x10aa09000 + 1389443 | ||
4 libnode.dylib 0x000000010ab678e9 0x10aa09000 + 1435881 |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
worker (in libnode.dylib) (threadpool.c:76) | ||
uv__thread_start (in libnode.dylib) (thread.c:54) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
const assert = require('assert') | ||
const atos = require('..') | ||
const fs = require('fs') | ||
const path = require('path') | ||
|
||
const {describe, it} = global | ||
|
||
describe('atos', function () { | ||
this.timeout(60000) | ||
|
||
const fixtures = path.join(__dirname, 'fixtures') | ||
|
||
it('returns an array of symbols for an Electron framework address', (done) => { | ||
atos({ | ||
file: path.join(fixtures, 'framework-addresses.txt'), | ||
version: '1.4.14' | ||
}, (error, symbols) => { | ||
if (error != null) return done(error) | ||
|
||
assert.equal(symbols.join('\n'), fs.readFileSync(path.join(fixtures, 'framework-symbols.txt'), 'utf8').trim()) | ||
done() | ||
}) | ||
}) | ||
|
||
it('returns an array of symbols for a node address', (done) => { | ||
atos({ | ||
file: path.join(fixtures, 'node-addresses.txt'), | ||
version: '1.4.14' | ||
}, (error, symbols) => { | ||
if (error != null) return done(error) | ||
|
||
assert.equal(symbols.join('\n'), fs.readFileSync(path.join(fixtures, 'node-symbols.txt'), 'utf8').trim()) | ||
done() | ||
}) | ||
}) | ||
}) |