leaked-handles
Advanced tools
Comparing version 5.1.0 to 5.2.0
25
index.js
'use strict'; | ||
var printHandles = require('./print-handles.js'); | ||
var printHandle = require('./print-handle.js'); | ||
@@ -12,2 +13,20 @@ var console = require('console'); | ||
(function wrapIt() { | ||
var EventEmitter = require('events').EventEmitter; | ||
var $emit = EventEmitter.prototype.emit; | ||
EventEmitter.prototype.emit = function fakeEmit(type, value) { | ||
if (type === 'error' && !this._events.error && | ||
(mutableConfig.debugErrors || mutableConfig.debugSockets) | ||
) { | ||
console.log('unhandled error', new Error().stack); | ||
printHandle(this, console, mutableConfig); | ||
// console.log('addr', this.address()); | ||
// console.log('server addr', this.server.address()); | ||
} | ||
return $emit.apply(this, arguments); | ||
}; | ||
}()); | ||
module.exports = { | ||
@@ -18,3 +37,3 @@ set: function set(opts) { | ||
if ('timeout' in opts) { | ||
printHandles.INTERVAL_HANDLE_TIMEOUT = opts.timeout + | ||
printHandle.INTERVAL_HANDLE_TIMEOUT = opts.timeout + | ||
Math.floor(Math.random() * 100); | ||
@@ -35,6 +54,6 @@ } | ||
timeoutHandle = setTimeout(handleInspectionLoop, | ||
printHandles.INTERVAL_HANDLE_TIMEOUT); | ||
printHandle.INTERVAL_HANDLE_TIMEOUT); | ||
timeoutHandle.unref(); | ||
}, printHandles.INTERVAL_HANDLE_TIMEOUT); | ||
}, printHandle.INTERVAL_HANDLE_TIMEOUT); | ||
timeoutHandle.unref(); | ||
}); |
{ | ||
"name": "leaked-handles", | ||
"version": "5.1.0", | ||
"version": "5.2.0", | ||
"description": "Detect any handles leaked in node", | ||
@@ -5,0 +5,0 @@ "keywords": [], |
'use strict'; | ||
var stacks = require('./stacks.js'); | ||
var path = require('path'); | ||
var process = require('process'); | ||
var nodeModules = path.sep + 'node_modules' + path.sep; | ||
printHandles.INTERVAL_HANDLE_TIMEOUT = 5001; | ||
var printHandle = require('./print-handle.js'); | ||
@@ -26,249 +22,7 @@ module.exports = printHandles; | ||
console.log('no of handles', handles.length); | ||
handles.forEach(printHandle); | ||
handles.forEach(function forHandle(h) { | ||
printHandle(h, console, config); | ||
}); | ||
console.log(''); | ||
console.log(''); | ||
function printHandle(obj) { | ||
console.log(''); | ||
if ('ontimeout' in obj) { | ||
if (obj && obj.msecs && | ||
obj.msecs === printHandles.INTERVAL_HANDLE_TIMEOUT | ||
) { | ||
console.log('timer handle (handleInspectLoop)'); | ||
} else if (obj && obj._repeat) { | ||
printTimer(obj, 'setInterval'); | ||
} else { | ||
printTimer(obj, 'setTimeout'); | ||
} | ||
} else if ('readable' in obj && 'writable' in obj) { | ||
// to debug stream handles print the _events functions | ||
// to string and figure out what kind of stream they are | ||
// then stare really hard at the source code | ||
// console.log(obj._events.end.toString()); | ||
if (stacks.childProcess.get(obj)) { | ||
printChildProcessStream(obj); | ||
} else if (obj._httpMessage) { | ||
printHttpStream(obj, 'http stream'); | ||
} else if (typeof obj.allowHalfOpen === 'boolean') { | ||
printTcpStream(obj, 'tcp stream'); | ||
} else { | ||
printStream(obj, 'stream handle'); | ||
} | ||
} else if ('pid' in obj) { | ||
printChildProcess(obj); | ||
} else if ('connections' in obj && | ||
'httpAllowHalfOpen' in obj | ||
) { | ||
printHttpServer(obj); | ||
} else if ('connections' in obj) { | ||
printTcpServer(obj); | ||
} else if (stacks.fileWatcher.get(obj)) { | ||
printFileWatcher(obj); | ||
} else { | ||
console.log('unknown handle', obj); | ||
} | ||
} | ||
function printTimer(obj, name) { | ||
var idleTimer = (obj && obj._idlePrev) || | ||
(obj && obj._idleNext); | ||
console.log(''); | ||
var fnName = idleTimer && idleTimer._onTimeout && | ||
idleTimer._onTimeout.name || 'fn'; | ||
var msg = 'timer handle (`' + name + '(' + fnName + | ||
', ' + obj.msecs + ')`)'; | ||
console.log(msg); | ||
if (obj.msecs && stacks.timeout.box.get(obj)) { | ||
printStack(stacks.timeout.box.get(obj).stack, | ||
'timer handle'); | ||
} else if (obj.msecs && | ||
stacks.timeout.stacks[obj.msecs] | ||
) { | ||
printStack(stacks.timeout.stacks[obj.msecs], | ||
'timer handle'); | ||
} | ||
if (!idleTimer) { | ||
console.log(obj); | ||
} else { | ||
console.log('timer listener', | ||
String(idleTimer._onTimeout)); | ||
} | ||
console.log(''); | ||
} | ||
function stackLineType(line) { | ||
var type; | ||
if (line.indexOf(nodeModules) >= 0) { | ||
type = 'node_modules'; | ||
} else if (line.indexOf(path.sep) >= 0) { | ||
type = 'default'; | ||
} else if (line.substring(0, 5) === 'Error') { | ||
type = 'error'; | ||
} else { | ||
type = 'node'; | ||
} | ||
return type; | ||
} | ||
function printStack(stacks, msg, opts) { | ||
opts = opts || {}; | ||
if (typeof stacks === 'string') { | ||
stacks = [stacks]; | ||
} | ||
var stackMsg = msg + ' leaked at one of: \n' + | ||
stacks.map(function print(s) { | ||
var lines = s.split('\n'); | ||
lines = lines.filter(function (line) { | ||
var type = stackLineType(line); | ||
return type === 'node_modules' || | ||
type === 'default'; | ||
}); | ||
return config.fullStack ? | ||
lines.join('\n') : | ||
lines[opts.frameOffset || 1]; | ||
}).reduce(function (acc, i) { | ||
if (acc.indexOf(i) === -1) { | ||
acc.push(i); | ||
} | ||
return acc; | ||
}, []).join('\n\n\n'); | ||
console.log(stackMsg); | ||
} | ||
function printTcpStream(obj, phrase) { | ||
var fd = obj._handle && obj._handle.fd; | ||
var readable = obj.readable; | ||
var writable = obj.writable; | ||
if (stacks.tcp.requests.get(obj)) { | ||
printStack(stacks.tcp.requests.get(obj).stack, | ||
'tcp handle'); | ||
} | ||
console.log(phrase, { | ||
fd: fd, | ||
readable: readable, | ||
writable: writable, | ||
address: obj.address() | ||
}); | ||
} | ||
function printFileWatcher(obj) { | ||
if (stacks.fileWatcher.get(obj)) { | ||
printStack(stacks.fileWatcher.get(obj).stack, | ||
'file watcher handle'); | ||
} | ||
var meta = stacks.fileWatcher.get(obj); | ||
console.log('file watcher handle', { | ||
filename: meta.filename | ||
}); | ||
} | ||
function printHttpServer(obj) { | ||
var fd = obj._handle && obj._handle.fd; | ||
if (stacks.http.servers.get(obj)) { | ||
printStack(stacks.http.servers.get(obj).stack, | ||
'http server handle'); | ||
} | ||
console.log('http server handle', { | ||
fd: fd, | ||
address: obj.address() | ||
}); | ||
} | ||
function printTcpServer(obj) { | ||
var fd = obj._handle && obj._handle.fd; | ||
if (stacks.tcp.servers.get(obj)) { | ||
printStack(stacks.tcp.servers.get(obj).stack, | ||
'tcp server handle'); | ||
} | ||
console.log('tcp server handle', { | ||
fd: fd, | ||
address: obj.address() | ||
}); | ||
} | ||
function printHttpStream(obj, phrase) { | ||
var fd = obj._handle && obj._handle.fd; | ||
var readable = obj.readable; | ||
var writable = obj.writable; | ||
var httpRequest = obj._httpMessage; | ||
var host = httpRequest && httpRequest._headers && | ||
httpRequest._headers.host; | ||
if (httpRequest && stacks.http.requests.get(httpRequest)) { | ||
printStack(stacks.http.requests.get(httpRequest).stack, | ||
'http handle'); | ||
} else if (stacks.tcp.requests.get(obj)) { | ||
printStack(stacks.tcp.requests.get(obj).stack, | ||
'tcp handle'); | ||
} | ||
console.log(phrase, { | ||
fd: fd, | ||
readable: readable, | ||
writable: writable, | ||
address: obj.address(), | ||
method: httpRequest && httpRequest.method, | ||
path: httpRequest && httpRequest.path, | ||
host: host | ||
}); | ||
} | ||
function printStream(obj, phrase) { | ||
var fd = obj._handle && obj._handle.fd; | ||
var readable = obj.readable; | ||
var writable = obj.writable; | ||
console.log(phrase, { | ||
fd: fd, | ||
readable: readable, | ||
writable: writable | ||
}); | ||
} | ||
function printChildProcessStream(obj) { | ||
if (stacks.childProcess.get(obj)) { | ||
var meta = stacks.childProcess.get(obj); | ||
printStack(meta.stack, | ||
'child process ' + meta.type + ' stream handle'); | ||
printStream(obj, | ||
'child process ' + meta.type + ' stream handle'); | ||
} else { | ||
printStream(obj, | ||
'child process stdio stream handle'); | ||
} | ||
} | ||
function printChildProcess(obj) { | ||
var meta = stacks.childProcess.get(obj); | ||
if (meta) { | ||
printStack(meta.stack, 'child process handle'); | ||
} | ||
console.log('child process handle', { | ||
pid: obj.pid, | ||
cmd: meta && meta.command, | ||
args: meta && meta.args | ||
}); | ||
} | ||
} |
@@ -46,3 +46,4 @@ # leaked-handles | ||
fullStack: true, // use full stack traces | ||
timeout: 30000 // run every 30 seconds instead of 5. | ||
timeout: 30000, // run every 30 seconds instead of 5. | ||
debugSockets: true // pretty print tcp thrown exceptions. | ||
}); | ||
@@ -49,0 +50,0 @@ ``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
26369
16
589
105