/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v26.7.0
test/common/debugger-probe.js
104 строки
4 KB
Joyee Cheung
test: normalize Windows crash in debugger test normalization
29 июл 2026, 16:31
Не верифицирован
29 июл 2026, 16:31
b3ff5fe
Код
Авторство
О чём код?
'use strict'; const assert = require('assert'); const { spawnSyncAndExit } = require('./child_process'); // Work around a pre-existing inspector issue: if the debuggee exits too quickly // the inspector can crash while tearing down. For now normalize the crash // back to the expected terminal event (e.g. "completed" or "miss") // until the upstream bug is fixed. // See https://github.com/nodejs/node/issues/62765 // https://github.com/nodejs/node/issues/58245 // The crash shows up as with exit code 3221225477 on Windows, or signal // SIGSEGV on other platforms. const probeTargetExitSignal = 'SIGSEGV'; // 0xC0000005 STATUS_ACCESS_VIOLATION on Windows const probeTargetExitCode = 3221225477; function isProbeSegvTeardown(result) { if (result?.event !== 'error') { return false; } const error = result.error; if (error?.signal !== probeTargetExitSignal && error?.exitCode !== probeTargetExitCode) { return false; } return error.code === 'probe_target_exit' || error.code === 'probe_failure'; } function findProbeSegvTeardownLine(output) { const signalPrefix = `Target exited with signal ${probeTargetExitSignal}`; const codePrefix = `Target exited with code ${probeTargetExitCode}`; for (const prefix of [signalPrefix, codePrefix]) { if (output.startsWith(prefix)) { return 0; } const idx = output.indexOf(`\n${prefix}`); if (idx !== -1) { return idx + 1; } } return -1; } // Replace volatile fields in a probe report (stack frames, Node.js version, // scriptId, callFrames) with stable placeholders for deepStrictEqual. function normalizeProbeReport(value) { if (typeof value === 'string') { return value .replace(/(?:\n[ \t]+at\s[^\n]*)+/g, '\n<stack>') .replace(/\nNode\.js v[^\n]+/g, '\nNode.js <version>'); } if (Array.isArray(value)) { return value.map(normalizeProbeReport); } if (value !== null && typeof value === 'object') { const result = {}; for (const key of Object.keys(value)) { if (key === 'scriptId') { result[key] = '<scriptId>'; } else if (key === 'callFrames') { result[key] = '<callFrames>'; } else { result[key] = normalizeProbeReport(value[key]); } } return result; } return value; } function assertProbeJson(output, expected) { const normalized = typeof output === 'string' ? JSON.parse(output) : output; const lastResult = normalized.results?.[normalized.results.length - 1]; if (isProbeSegvTeardown(lastResult)) { // Log to facilitate debugging if this normalization is occurring. console.log('Normalizing trailing SIGSEGV in JSON probe output'); normalized.results[normalized.results.length - 1] = expected.results.at(-1); } assert.deepStrictEqual(normalizeProbeReport(normalized), normalizeProbeReport(expected)); } function assertProbeText(output, expected) { const lineStart = findProbeSegvTeardownLine(output); let normalized; if (lineStart !== -1) { // Log to facilitate debugging if this normalization is occurring. console.log('Normalizing trailing SIGSEGV in text probe output'); const expectedLineStart = expected.lastIndexOf('\n'); const terminalLine = expectedLineStart === -1 ? expected : expected.slice(expectedLineStart + 1); normalized = lineStart === 0 ? terminalLine : `${output.slice(0, lineStart - 1)}\n${terminalLine}`; } else { normalized = output; } assert.strictEqual(normalized, expected); } function assertProbeCliError(inspectArgs, expectedStderr, { cwd } = {}) { spawnSyncAndExit(process.execPath, ['inspect', ...inspectArgs], { cwd }, { signal: null, status: 9, stderr: expectedStderr, trim: true, }); } module.exports = { assertProbeJson, assertProbeCliError, assertProbeText, };