Skip to content

Commit

Permalink
watcher - enable crash reports on linux (#136264)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Nov 3, 2021
1 parent fd3b9ad commit af26148
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 11 deletions.
Expand Up @@ -195,7 +195,7 @@ class SharedProcessMain extends Disposable {
services.set(ILogService, logService);

// Worker
this.sharedProcessWorkerService = new SharedProcessWorkerService(logService);
this.sharedProcessWorkerService = new SharedProcessWorkerService(logService, productService, environmentService);
services.set(ISharedProcessWorkerService, this.sharedProcessWorkerService);

// Files
Expand Down
Expand Up @@ -29,6 +29,11 @@ export interface ISharedProcessWorkerEnvironment {
* Full absolute path to our `bootstrap-fork.js` file.
*/
bootstrapPath: string;

/**
* Extra environment to use for the process to fork.
*/
env: NodeJS.ProcessEnv;
}

interface IBaseMessage {
Expand Down
Expand Up @@ -124,7 +124,7 @@ class SharedProcessWorkerProcess extends Disposable {
}

spawn(): void {
Logger.trace('Forking worker process');
Logger.trace(`Forking worker process (env: ${JSON.stringify(this.environment.env)})`);

// Fork module via bootstrap-fork for AMD support
this.child = fork(
Expand Down Expand Up @@ -194,6 +194,7 @@ class SharedProcessWorkerProcess extends Disposable {
private getEnv(): NodeJS.ProcessEnv {
const env: NodeJS.ProcessEnv = {
...deepClone(process.env),
...this.environment.env,
VSCODE_AMD_ENTRYPOINT: this.configuration.process.moduleId,
VSCODE_PIPE_LOGGING: 'true',
VSCODE_VERBOSE_LOGGING: 'true',
Expand Down
Expand Up @@ -3,15 +3,19 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ipcRenderer } from 'electron';
import { CrashReporterStartOptions, ipcRenderer } from 'electron';
import { join } from 'path';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { FileAccess } from 'vs/base/common/network';
import { generateUuid } from 'vs/base/common/uuid';
import { isLinux } from 'vs/base/common/platform';
import { generateUuid, isUUID } from 'vs/base/common/uuid';
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
import { IProductService } from 'vs/platform/product/common/productService';
import { hash, IOnDidTerminateSharedProcessWorkerProcess, ISharedProcessWorkerConfiguration, ISharedProcessWorkerProcessExit, ISharedProcessWorkerService } from 'vs/platform/sharedProcess/common/sharedProcessWorkerService';
import { SharedProcessWorkerMessages, ISharedProcessToWorkerMessage, IWorkerToSharedProcessMessage } from 'vs/platform/sharedProcess/electron-browser/sharedProcessWorker';
import { SharedProcessWorkerMessages, ISharedProcessToWorkerMessage, IWorkerToSharedProcessMessage, ISharedProcessWorkerEnvironment } from 'vs/platform/sharedProcess/electron-browser/sharedProcessWorker';

export class SharedProcessWorkerService implements ISharedProcessWorkerService {

Expand All @@ -23,7 +27,9 @@ export class SharedProcessWorkerService implements ISharedProcessWorkerService {
private readonly processResolvers = new Map<number /* process configuration hash */, (process: IOnDidTerminateSharedProcessWorkerProcess) => void>();

constructor(
@ILogService private readonly logService: ILogService
@ILogService private readonly logService: ILogService,
@IProductService private readonly productService: IProductService,
@INativeEnvironmentService private readonly environmentService: INativeEnvironmentService
) {
}

Expand Down Expand Up @@ -117,7 +123,7 @@ export class SharedProcessWorkerService implements ISharedProcessWorkerService {
if (!webWorkerPromise) {
this.logService.trace(`SharedProcess: creating new web worker (${configuration.process.moduleId})`);

const sharedProcessWorker = new SharedProcessWebWorker(configuration.process.type, this.logService);
const sharedProcessWorker = new SharedProcessWebWorker(configuration.process.type, this.logService, this.productService, this.environmentService);
webWorkerPromise = sharedProcessWorker.init();

// Make sure to run through our normal `disposeWorker` call
Expand Down Expand Up @@ -156,7 +162,9 @@ class SharedProcessWebWorker extends Disposable {

constructor(
private readonly type: string,
private readonly logService: ILogService
private readonly logService: ILogService,
private readonly productService: IProductService,
private readonly environmentService: INativeEnvironmentService
) {
super();
}
Expand Down Expand Up @@ -280,14 +288,47 @@ class SharedProcessWebWorker extends Disposable {
const workerMessage: ISharedProcessToWorkerMessage = {
id: SharedProcessWorkerMessages.Spawn,
configuration,
environment: {
bootstrapPath: FileAccess.asFileUri('bootstrap-fork', require).fsPath
}
environment: this.getSharedProcessWorkerEnvironment()
};

return this.send(workerMessage, token, port);
}

private getSharedProcessWorkerEnvironment(): ISharedProcessWorkerEnvironment {
const sharedProcessWorkerEnvironment = {
bootstrapPath: FileAccess.asFileUri('bootstrap-fork', require).fsPath,
env: Object.create(null)
};

// Crash reporter support
// TODO@bpasero TODO@deepak1556 remove once we updated to Electron 15
if (isLinux) {
const crashReporterStartOptions: CrashReporterStartOptions = {
companyName: this.productService.crashReporter?.companyName || 'Microsoft',
productName: this.productService.crashReporter?.productName || this.productService.nameShort,
submitURL: '',
uploadToServer: false
};

const crashReporterId = this.environmentService.args['crash-reporter-id']; // crashReporterId is set by the main process only when crash reporting is enabled by the user.
const appcenter = this.productService.appCenter;
const uploadCrashesToServer = !this.environmentService.args['crash-reporter-directory']; // only upload unless --crash-reporter-directory is provided
if (uploadCrashesToServer && appcenter && crashReporterId && isUUID(crashReporterId)) {
const submitURL = appcenter[`linux-x64`];
crashReporterStartOptions.submitURL = submitURL.concat('&uid=', crashReporterId, '&iid=', crashReporterId, '&sid=', crashReporterId);
crashReporterStartOptions.uploadToServer = true;
}
// In the upload to server case, there is a bug in electron that creates client_id file in the current
// working directory. Setting the env BREAKPAD_DUMP_LOCATION will force electron to create the file in that location,
// For https://github.com/microsoft/vscode/issues/105743
const extHostCrashDirectory = this.environmentService.args['crash-reporter-directory'] || this.environmentService.userDataPath;
sharedProcessWorkerEnvironment.env.BREAKPAD_DUMP_LOCATION = join(extHostCrashDirectory, `Parcel Watcher Crash Reports`);
sharedProcessWorkerEnvironment.env.VSCODE_CRASH_REPORTER_START_OPTIONS = JSON.stringify(crashReporterStartOptions);
}

return sharedProcessWorkerEnvironment;
}

terminate(configuration: ISharedProcessWorkerConfiguration, token: CancellationToken): Promise<void> {
const workerMessage: ISharedProcessToWorkerMessage = {
id: SharedProcessWorkerMessages.Terminate,
Expand Down
Expand Up @@ -277,6 +277,7 @@ export class LocalProcessExtensionHost implements IExtensionHost {
}

// On linux crash reporter needs to be started on child node processes explicitly
// TODO@bpasero TODO@deepak1556 remove once we updated to Electron 15
if (platform.isLinux) {
const crashReporterStartOptions: CrashReporterStartOptions = {
companyName: this._productService.crashReporter?.companyName || 'Microsoft',
Expand Down

0 comments on commit af26148

Please sign in to comment.