watcher - enable crash reports on linux (#136264)

This commit is contained in:
Benjamin Pasero 2021-11-03 08:28:48 +01:00
parent fd3b9ada8e
commit af261488f8
No known key found for this signature in database
GPG key ID: E6380CC4C8219E65
5 changed files with 59 additions and 11 deletions

View file

@ -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

View file

@ -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 {

View file

@ -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(
@ -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',

View file

@ -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 {
@ -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
) {
}
@ -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
@ -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();
}
@ -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,

View file

@ -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',