1'use strict'; 2 3// Testcases for situations involving fatal errors, like Javascript heap OOM 4 5require('../common'); 6const assert = require('assert'); 7const fs = require('fs'); 8const helper = require('../common/report.js'); 9const spawnSync = require('child_process').spawnSync; 10const tmpdir = require('../common/tmpdir'); 11 12if (process.argv[2] === 'child') { 13 14 const list = []; 15 while (true) { 16 const record = new MyRecord(); 17 list.push(record); 18 } 19 20 function MyRecord() { 21 this.name = 'foo'; 22 this.id = 128; 23 this.account = 98454324; 24 } 25} 26 27// Common args that will cause an out-of-memory error for child process. 28const ARGS = [ 29 '--max-old-space-size=20', 30 __filename, 31 'child', 32]; 33 34{ 35 // Verify that --report-on-fatalerror is respected when set. 36 tmpdir.refresh(); 37 const args = ['--report-on-fatalerror', ...ARGS]; 38 const child = spawnSync(process.execPath, args, { cwd: tmpdir.path }); 39 assert.notStrictEqual(child.status, 0, 'Process exited unexpectedly'); 40 41 const reports = helper.findReports(child.pid, tmpdir.path); 42 assert.strictEqual(reports.length, 1); 43 44 const report = reports[0]; 45 helper.validate(report); 46 47 // Errors occur in a context where env is not available, so thread ID is 48 // unknown. Assert this, to verify that the underlying env-less situation is 49 // actually reached. 50 assert.strictEqual(require(report).header.threadId, null); 51} 52 53{ 54 // Verify that --report-on-fatalerror is respected when not set. 55 const args = ARGS; 56 const child = spawnSync(process.execPath, args, { cwd: tmpdir.path }); 57 assert.notStrictEqual(child.status, 0, 'Process exited unexpectedly'); 58 const reports = helper.findReports(child.pid, tmpdir.path); 59 assert.strictEqual(reports.length, 0); 60} 61 62{ 63 // Verify that --report-directory is respected when set. 64 // Verify that --report-compact is respected when not set. 65 tmpdir.refresh(); 66 const dir = '--report-directory=' + tmpdir.path; 67 const args = ['--report-on-fatalerror', dir, ...ARGS]; 68 const child = spawnSync(process.execPath, args, { }); 69 assert.notStrictEqual(child.status, 0, 'Process exited unexpectedly'); 70 71 const reports = helper.findReports(child.pid, tmpdir.path); 72 assert.strictEqual(reports.length, 1); 73 74 const report = reports[0]; 75 helper.validate(report); 76 assert.strictEqual(require(report).header.threadId, null); 77 const lines = fs.readFileSync(report, 'utf8').split('\n').length - 1; 78 assert(lines > 10); 79} 80 81{ 82 // Verify that --report-compact is respected when set. 83 tmpdir.refresh(); 84 const args = ['--report-on-fatalerror', '--report-compact', ...ARGS]; 85 const child = spawnSync(process.execPath, args, { cwd: tmpdir.path }); 86 assert.notStrictEqual(child.status, 0, 'Process exited unexpectedly'); 87 88 const reports = helper.findReports(child.pid, tmpdir.path); 89 assert.strictEqual(reports.length, 1); 90 91 const report = reports[0]; 92 helper.validate(report); 93 assert.strictEqual(require(report).header.threadId, null); 94 // Subtract 1 because "xx\n".split("\n") => [ 'xx', '' ]. 95 const lines = fs.readFileSync(report, 'utf8').split('\n').length - 1; 96 assert.strictEqual(lines, 1); 97} 98 99{ 100 // Verify that --report-compact is respected when set. 101 // Verify that --report-filename is respected when set. 102 tmpdir.refresh(); 103 const args = [ 104 '--report-on-fatalerror', 105 '--report-compact', 106 '--report-filename=stderr', 107 ...ARGS, 108 ]; 109 const child = spawnSync(process.execPath, args, { encoding: 'utf8' }); 110 assert.notStrictEqual(child.status, 0, 'Process exited unexpectedly'); 111 112 const reports = helper.findReports(child.pid, tmpdir.path); 113 assert.strictEqual(reports.length, 0); 114 115 const lines = child.stderr.split('\n'); 116 // Skip over unavoidable free-form output and gc log from V8. 117 const report = lines.find((i) => i.startsWith('{')); 118 const json = JSON.parse(report); 119 120 assert.strictEqual(json.header.threadId, null); 121} 122