Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix childprocess killing when the parent process SIGINTs #6011

Merged
merged 8 commits into from Jun 15, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions mocha-config/base.js
@@ -1,4 +1,6 @@
module.exports = {
reporter: 'dot',
// Allow `console.logs` to show up during test execution
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
// Allow `console.logs` to show up during test execution
// Allow `console.log`s to show up during test execution

logLevel: 'debug',
exit: !!process.env.CI,
};
35 changes: 23 additions & 12 deletions src/launcher/BrowserRunner.ts
Expand Up @@ -28,6 +28,10 @@ import { TimeoutError } from '../Errors';

const removeFolderAsync = helper.promisify(removeFolder);
const debugLauncher = debug('puppeteer:launcher');
const PROCESS_ERROR_EXPLANATION = `Puppeteer was unable to kill the process which ran the browser binary.
This means that, on future Puppeteer launches, Puppeteer might not be able to launch the browser.
Please check your open processes and ensure that the browser processes that Puppeteer launched have been killed.
If you think this is a bug, please report it on the Puppeteer issue tracker.`;

export class BrowserRunner {
private _executablePath: string;
Expand All @@ -51,7 +55,7 @@ export class BrowserRunner {
this._tempDirectory = tempDirectory;
}

start(options: LaunchOptions = {}): void {
start(options: LaunchOptions): void {
const {
handleSIGINT,
handleSIGTERM,
Expand Down Expand Up @@ -121,7 +125,6 @@ export class BrowserRunner {

close(): Promise<void> {
if (this._closed) return Promise.resolve();
helper.removeEventListeners(this._listeners);
if (this._tempDirectory) {
this.kill();
} else if (this.connection) {
Expand All @@ -131,24 +134,32 @@ export class BrowserRunner {
this.kill();
});
}
// Cleanup this listener last, as that makes sure the full callback runs. If we
// perform this earlier, then the previous function calls would not happen.
helper.removeEventListeners(this._listeners);
return this._processClosing;
}

kill(): void {
helper.removeEventListeners(this._listeners);
if (this.proc && this.proc.pid && !this.proc.killed && !this._closed) {
try {
if (process.platform === 'win32')
childProcess.execSync(`taskkill /pid ${this.proc.pid} /T /F`);
else process.kill(-this.proc.pid, 'SIGKILL');
} catch (error) {
// the process might have already stopped
}
}
// Attempt to remove temporary profile directory to avoid littering.
try {
removeFolder.sync(this._tempDirectory);
} catch (error) {}

// If the process failed to launch (for example if the browser executable path
// is invalid), then the process does not get a pid assigned. A call to
// `proc.kill` would error, as the `pid` to-be-killed can not be found.
if (this.proc && this.proc.pid && !this.proc.killed) {
try {
this.proc.kill('SIGKILL');
} catch (error) {
throw new Error(`${PROCESS_ERROR_EXPLANATION}
Error cause: ${error.stack}`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit to maintain indentation:

Suggested change
throw new Error(`${PROCESS_ERROR_EXPLANATION}
Error cause: ${error.stack}`);
throw new Error(`${PROCESS_ERROR_EXPLANATION}\nError cause: ${error.stack}`);

}
}
// Cleanup this listener last, as that makes sure the full callback runs. If we
// perform this earlier, then the previous function calls would not happen.
helper.removeEventListeners(this._listeners);
}

async setupConnection(options: {
Expand Down
2 changes: 1 addition & 1 deletion test/mocha-utils.js
Expand Up @@ -71,7 +71,7 @@ try {

const defaultBrowserOptions = Object.assign(
{
handleSIGINT: false,
handleSIGINT: true,
executablePath: process.env.BINARY,
slowMo: false,
headless: isHeadless,
Expand Down