forked from mafintosh/why-is-node-running
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
117 lines (95 loc) · 3.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
var core = require('./core')
var b = process.binding
process.binding = function (name) {
var loaded = b(name)
var cpy = {}
Object.keys(loaded).forEach(function (prop) {
if (typeof loaded[prop] === 'function' && loaded[prop].prototype) {
var wrap = function () {
var handle
if (arguments.length === 4) handle = new loaded[prop](arguments[0], arguments[1], arguments[2], arguments[3])
else if (arguments.length === 3) handle = new loaded[prop](arguments[0], arguments[1], arguments[2])
else if (arguments.length === 2) handle = new loaded[prop](arguments[0], arguments[1])
else if (arguments.length === 1) handle = new loaded[prop](arguments[0])
else handle = new loaded[prop]()
var e = new Error('whatevs')
var stacks = require('stackback')(e)
handle.__WHY_IS_NODE_RUNNING__ = {stacks: [], wrapped: loaded[prop]}
for (var i = 1; i < stacks.length; i++) {
handle.__WHY_IS_NODE_RUNNING__.stacks.push(stacks[i])
}
return handle
}
Object.keys(loaded[prop]).forEach(function (name) {
wrap[name] = loaded[prop][name]
})
if (/^[A-Z]/.test(prop)) {
cpy[prop] = wrap
} else {
cpy[prop] = loaded[prop]
}
} else {
cpy[prop] = loaded[prop]
}
})
return cpy
}
core.globalTimeouts()
module.exports = function (logger) {
logger = logger || console
var handles = process._getActiveHandles()
var unknown = []
var known = []
handles.forEach(function (handle) {
var stacks = findStacks(handle, 0)
if (stacks) {
known.push(stacks)
} else {
unknown.push(handle)
}
})
logger.error('There are %d known handle(s) keeping the process running and %d unknown', known.length, unknown.length)
logger.error('Known handles:\n')
known.forEach(function (obj, i) {
var stacks = obj.stacks
stacks = stacks.filter(function (s) {
return s.getFileName().indexOf(require('path').sep) > -1
})
logger.error('# %s', obj.wrapped.name)
if (!stacks[0]) {
logger.error('(unknown stack trace)')
} else {
var padding = ''
stacks.forEach(function (s) {
var pad = (s.getFileName() + ':' + s.getLineNumber()).replace(/./g, ' ')
if (pad.length > padding.length) padding = pad
})
stacks.forEach(function (s) {
var prefix = s.getFileName() + ':' + s.getLineNumber()
try {
var src = require('fs').readFileSync(s.getFileName(), 'utf-8').split(/\n|\r\n/)
logger.error(prefix + padding.slice(prefix.length) + ' - ' + src[s.getLineNumber() - 1].trim())
} catch (e) {
logger.error(prefix + padding.slice(prefix.length))
}
})
}
logger.error('\nUnknown handles:\n')
unknown.forEach(function (stack) {
logger.error(stack)
logger.error()
})
})
}
function findStacks (obj, depth) {
if (depth === 10) return null
var keys = Object.keys(obj)
for (var i = 0; i < keys.length; i++) {
var val = obj[keys[i]]
if (keys[i] === '__WHY_IS_NODE_RUNNING__') return val
if (typeof val === 'object' && val) {
val = findStacks(val, depth + 1)
if (val) return val
}
}
}