Created
November 12, 2015 14:14
-
-
Save evanlucas/e631ae36a066695f0394 to your computer and use it in GitHub Desktop.
llnode test
This file contains hidden or 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
'use strict' | |
if (process.argv[2]) { | |
var server = require('http').createServer(function(req, res) { | |
req.date = new Date(+process.argv[2]) | |
res.writeHead(200, { | |
'Content-Type': 'text/plain' | |
}) | |
res.end('10000') | |
server.close() | |
}).listen(3000, '127.0.0.1', function(err) { | |
if (err) throw err | |
console.log('LISTEN') | |
}) | |
return | |
} | |
const spawn = require('child_process').spawn | |
var d = Date.now() | |
const child = spawn('/usr/bin/env', ['lldb', '--', 'node', __filename, d], { | |
env: process.env | |
, cwd: __dirname | |
}) | |
var isListening = false | |
var expectingBT = false | |
var expectingIM = 0 | |
child.stdout.on('data', function(chunk) { | |
var data = chunk.toString() | |
//console.log('stdout', data) | |
if (/Process ([^\s]+) exited/.test(data)) { | |
child.kill('SIGTERM') | |
} | |
if (expectingBT) { | |
var lines = data.split('\n') | |
var imAddress = findIncomingMessageAddress(lines) | |
if (imAddress) { | |
expectingBT = false | |
expectingIM = 1 | |
write(`v8 i ${imAddress}`) | |
} | |
} | |
if (expectingIM) { | |
if (expectingIM === 3) { | |
if (!verifyIncomingMessage(data)) { | |
console.log('not ok # verify IncomingMessage') | |
} else { | |
console.log('ok # verify IncomingMessage') | |
write('c') | |
} | |
} | |
expectingIM++ | |
} | |
if (~data.indexOf('settings set -- target.run-args')) { | |
write('b DoWrite') | |
write('r') | |
} | |
if (/launched/.test(data)) { | |
setTimeout(function() { | |
curl() | |
}, 1000) | |
} | |
if (/stopped/.test(data)) { | |
// hit a breakpoint | |
// get v8 bt | |
expectingBT = true | |
write('v8 bt') | |
} | |
}) | |
child.stderr.on('data', function(chunk) { | |
console.log('stderr', chunk.toString()) | |
}) | |
child.on('close', process.exit) | |
process.stdin.pipe(child.stdin) | |
process.on('exit', function() { | |
child.kill('SIGTERM') | |
}) | |
function curl() { | |
require('http').get('http://localhost:3000/', function(res) { | |
}).on('error', function(err) { | |
console.error('err', err) | |
}) | |
} | |
function write(d) { | |
child.stdin.write(d) | |
child.stdin.write('\n') | |
} | |
function findIncomingMessageAddress(lines) { | |
var results = {} | |
for (var i = 1, l = lines.length; i < l; i++) { | |
var line = lines[i] | |
var frame = parseFrame(line) | |
if (frame && frame.details) { | |
var dets = parseFrameDetails(frame.details) | |
for (var j = 0, k = dets.length; j < k; j++) { | |
var det = dets[j] | |
if (det.type === '<Object: IncomingMessage>') { | |
return det.address | |
} | |
} | |
} | |
} | |
return null | |
} | |
function parseFrame(line) { | |
var match = line.match(/frame #([^:]+): ([^\s]+) (.*)/) | |
if (!match) return null | |
return { | |
frame: match[1] | |
, address: match[2] | |
, details: match[3] | |
} | |
} | |
function parseFrameDetails(details) { | |
var match = details.match(/0x([^:]+):\<([^\>]+)>/g) | |
if (match && Array.isArray(match)) { | |
return match.map(function(item) { | |
var items = item.split(':') | |
var add = items.shift() | |
var type = items.join(':') | |
return { | |
address: add | |
, type: type | |
} | |
}) | |
} else { | |
return [] | |
} | |
} | |
function verifyIncomingMessage(data) { | |
if (!/httpVersionMajor=<Smi: 1>/.test(data)) | |
return false | |
if (!/httpVersionMinor=<Smi: 1>/.test(data)) | |
return false | |
if (!/method=([^:]+):<String: "GET">/.test(data)) | |
return false | |
var dre = new RegExp('date=([^:]+):<JSDate: ' + d + '>') | |
if (!dre.test(data)) | |
return false | |
return true | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment