gitnexus 1.6.6-rc.4 → 1.6.6-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/analyze.js +54 -3
- package/package.json +1 -1
package/dist/cli/analyze.js
CHANGED
|
@@ -58,12 +58,55 @@ const installFatalHandlers = () => {
|
|
|
58
58
|
process.exit(1);
|
|
59
59
|
});
|
|
60
60
|
};
|
|
61
|
-
const HEAP_MB =
|
|
62
|
-
const
|
|
61
|
+
const HEAP_MB = 16384;
|
|
62
|
+
const TEST_RESPAWN_HEAP_MB = Number(process.env.GITNEXUS_TEST_RESPAWN_HEAP_MB);
|
|
63
|
+
const RESPAWN_HEAP_MB = Number.isFinite(TEST_RESPAWN_HEAP_MB) && TEST_RESPAWN_HEAP_MB > 0
|
|
64
|
+
? Math.floor(TEST_RESPAWN_HEAP_MB)
|
|
65
|
+
: HEAP_MB;
|
|
66
|
+
const HEAP_FLAG = `--max-old-space-size=${RESPAWN_HEAP_MB}`;
|
|
63
67
|
/** Increase default stack size (KB) to prevent stack overflow on deep class hierarchies. */
|
|
64
68
|
const STACK_KB = 4096;
|
|
65
69
|
const STACK_FLAG = `--stack-size=${STACK_KB}`;
|
|
66
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Heuristic for "child re-exec likely died from V8 OOM".
|
|
72
|
+
*
|
|
73
|
+
* Platform-independent detection is best-effort: V8/Node usually emit
|
|
74
|
+
* stable heap-exhaustion phrases in stderr/message across Linux/macOS/Windows
|
|
75
|
+
* (for example "JavaScript heap out of memory" or "Reached heap limit"),
|
|
76
|
+
* while some environments only expose status/signal (e.g. 134/SIGABRT).
|
|
77
|
+
* We combine both text signatures and process-exit signatures.
|
|
78
|
+
*/
|
|
79
|
+
const childProcessLikelyOom = (err) => {
|
|
80
|
+
if (!err || typeof err !== 'object')
|
|
81
|
+
return false;
|
|
82
|
+
const e = err;
|
|
83
|
+
const hasHeapOomSignature = (v) => {
|
|
84
|
+
const text = (Buffer.isBuffer(v) ? v.toString('utf8') : typeof v === 'string' ? v : '').toLowerCase();
|
|
85
|
+
if (!text)
|
|
86
|
+
return false;
|
|
87
|
+
return (text.includes('javascript heap out of memory') ||
|
|
88
|
+
text.includes('reached heap limit') ||
|
|
89
|
+
text.includes('allocation failed - javascript heap out of memory') ||
|
|
90
|
+
text.includes('fatalprocessoutofmemory'));
|
|
91
|
+
};
|
|
92
|
+
const fields = [e.message, e.stderr, e.stdout];
|
|
93
|
+
if (fields.some((v) => hasHeapOomSignature(v)))
|
|
94
|
+
return true;
|
|
95
|
+
const hasAnyChildOutput = [e.stderr, e.stdout].some((v) => (Buffer.isBuffer(v) && v.length > 0) || (typeof v === 'string' && v.length > 0));
|
|
96
|
+
if (hasAnyChildOutput)
|
|
97
|
+
return false;
|
|
98
|
+
return e.status === 134 || e.signal === 'SIGABRT';
|
|
99
|
+
};
|
|
100
|
+
const forceHeapOOMForTestIfEnabled = () => {
|
|
101
|
+
if (process.env.GITNEXUS_TEST_FORCE_HEAP_OOM !== '1')
|
|
102
|
+
return;
|
|
103
|
+
// Allocate JS strings (not Buffers) so pressure lands on V8 heap itself.
|
|
104
|
+
// Buffers can allocate off-heap, which makes OOM triggering less reliable.
|
|
105
|
+
const chunks = [];
|
|
106
|
+
for (;;)
|
|
107
|
+
chunks.push('x'.repeat(1024 * 1024));
|
|
108
|
+
};
|
|
109
|
+
/** Re-exec the process with a 16GB heap and larger stack if we're currently below that. */
|
|
67
110
|
function ensureHeap() {
|
|
68
111
|
const nodeOpts = process.env.NODE_OPTIONS || '';
|
|
69
112
|
if (nodeOpts.includes('--max-old-space-size'))
|
|
@@ -83,6 +126,13 @@ function ensureHeap() {
|
|
|
83
126
|
});
|
|
84
127
|
}
|
|
85
128
|
catch (e) {
|
|
129
|
+
if (childProcessLikelyOom(e)) {
|
|
130
|
+
cliError(` Analysis likely ran out of memory.\n` +
|
|
131
|
+
` Retry with a larger heap if your machine allows it:\n` +
|
|
132
|
+
` NODE_OPTIONS="--max-old-space-size=24576" gitnexus analyze [your-args]\n` +
|
|
133
|
+
` (Windows: set NODE_OPTIONS=--max-old-space-size=24576 && gitnexus analyze [your-args])\n` +
|
|
134
|
+
` If this persists, it may be a native crash unrelated to heap size.\n`, { recoveryHint: 'heap-oom-respawn' });
|
|
135
|
+
}
|
|
86
136
|
process.exitCode = e.status ?? 1;
|
|
87
137
|
}
|
|
88
138
|
return true;
|
|
@@ -104,6 +154,7 @@ export const shouldGenerateCommunitySkillFiles = (options, pipelineResult) => Bo
|
|
|
104
154
|
export const analyzeCommand = async (inputPath, options) => {
|
|
105
155
|
if (ensureHeap())
|
|
106
156
|
return;
|
|
157
|
+
forceHeapOOMForTestIfEnabled();
|
|
107
158
|
// Install fatal handlers immediately after re-exec resolution so any
|
|
108
159
|
// async error that escapes the try/catch below (#1169) surfaces with
|
|
109
160
|
// a stack trace and a non-zero exit code instead of a silent exit 0.
|
package/package.json
CHANGED