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