diff --git a/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts b/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts index 074e9ecb3e6b4..d05bd7ca0c42b 100644 --- a/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts +++ b/src/vs/platform/debug/electron-main/extensionHostDebugIpc.ts @@ -27,6 +27,8 @@ export class ElectronExtensionHostDebugBroadcastChannel extends Extens private async openExtensionDevelopmentHostWindow(args: string[], env: IProcessEnvironment, debugRenderer: boolean): Promise { const pargs = parseArgs(args, OPTIONS); + pargs.debugRenderer = debugRenderer; + const extDevPaths = pargs.extensionDevelopmentPath; if (!extDevPaths) { return {}; diff --git a/src/vs/platform/environment/common/argv.ts b/src/vs/platform/environment/common/argv.ts index 2ac99a2120ec4..dcb450dc3a1d0 100644 --- a/src/vs/platform/environment/common/argv.ts +++ b/src/vs/platform/environment/common/argv.ts @@ -43,6 +43,7 @@ export interface NativeParsedArgs { 'inspect-extensions'?: string; 'inspect-brk-extensions'?: string; debugId?: string; + debugRenderer?: boolean; // whether we expect a debugger (js-debug) to attach to the renderer, incl webviews+webworker 'inspect-search'?: string; 'inspect-brk-search'?: string; 'disable-extensions'?: boolean; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 662547909e57b..ef0b7c5e9909f 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -83,6 +83,7 @@ export const OPTIONS: OptionDescriptions> = { 'extensionDevelopmentPath': { type: 'string[]' }, 'extensionTestsPath': { type: 'string' }, 'debugId': { type: 'string' }, + 'debugRenderer': { type: 'boolean' }, 'inspect-search': { type: 'string', deprecates: 'debugSearch' }, 'inspect-brk-search': { type: 'string', deprecates: 'debugBrkSearch' }, 'export-default-configuration': { type: 'string' }, diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 16057c43a0807..06838a8bdd957 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -189,6 +189,7 @@ export class NativeEnvironmentService implements INativeEnvironmentService { @memoize get debugExtensionHost(): IExtensionHostDebugParams { return parseExtensionHostPort(this._args, this.isBuilt); } + get debugRenderer(): boolean { return !!this._args.debugRenderer; } get isBuilt(): boolean { return !process.env['VSCODE_DEV']; } get verbose(): boolean { return !!this._args.verbose; } diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index a6a149083719d..021af6e0f8983 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -10,6 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ExtensionRuntime } from 'vs/workbench/api/common/extHostTypes'; +import { timeout } from 'vs/base/common/async'; class WorkerRequireInterceptor extends RequireInterceptor { @@ -41,6 +42,7 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { const apiFactory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors); this._fakeModules = this._instaService.createInstance(WorkerRequireInterceptor, apiFactory, this._registry); await this._fakeModules.install(); + await this._waitForDebuggerAttachment(); } protected _getEntryPoint(extensionDescription: IExtensionDescription): string | undefined { @@ -86,6 +88,18 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { async $setRemoteEnvironment(_env: { [key: string]: string | null }): Promise { throw new Error('Not supported'); } + + private async _waitForDebuggerAttachment(waitTimeout = 5000) { + // debugger attaches async, waiting for it fixes #106698 and #99222 + if (!this._initData.environment.isExtensionDevelopmentDebug) { + return; + } + + const deadline = Date.now() + waitTimeout; + while (Date.now() < deadline && !('__jsDebugIsReady' in globalThis)) { + await timeout(10); + } + } } function ensureSuffix(path: string, suffix: string): string { diff --git a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts index b58aed30c99d3..512b3a57237dc 100644 --- a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts +++ b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts @@ -105,6 +105,7 @@ export class SimpleNativeWorkbenchEnvironmentService implements INativeWorkbench keyboardLayoutResource: URI = undefined!; sync: 'on' | 'off' | undefined; debugExtensionHost: IExtensionHostDebugParams = undefined!; + debugRenderer = false; isExtensionDevelopment: boolean = false; disableExtensions: boolean | string[] = []; extensionDevelopmentLocationURI?: URI[] | undefined; diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 50e314294c0fe..e77b8185c341d 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -82,6 +82,7 @@ interface IBrowserWorkbenchOptions extends IWorkbenchOptions { interface IExtensionHostDebugEnvironment { params: IExtensionHostDebugParams; + debugRenderer: boolean; isExtensionDevelopment: boolean; extensionDevelopmentLocationURI?: URI[]; extensionTestsLocationURI?: URI; @@ -206,6 +207,14 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment return this._extensionHostDebugEnvironment.extensionEnabledProposedApi; } + get debugRenderer(): boolean { + if (!this._extensionHostDebugEnvironment) { + this._extensionHostDebugEnvironment = this.resolveExtensionHostDebugEnvironment(); + } + + return this._extensionHostDebugEnvironment.debugRenderer; + } + get disableExtensions() { return this.payload?.get('disableExtensions') === 'true'; } private get webviewEndpoint(): string { @@ -257,6 +266,7 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment port: null, break: false }, + debugRenderer: false, isExtensionDevelopment: false, extensionDevelopmentLocationURI: undefined }; @@ -272,6 +282,9 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment case 'extensionTestsPath': extensionHostDebugEnvironment.extensionTestsLocationURI = URI.parse(value); break; + case 'debugRenderer': + extensionHostDebugEnvironment.debugRenderer = value === 'true'; + break; case 'debugId': extensionHostDebugEnvironment.params.debugId = value; break; diff --git a/src/vs/workbench/services/environment/common/environmentService.ts b/src/vs/workbench/services/environment/common/environmentService.ts index d2510cacfb964..914f493cd32a2 100644 --- a/src/vs/workbench/services/environment/common/environmentService.ts +++ b/src/vs/workbench/services/environment/common/environmentService.ts @@ -45,6 +45,8 @@ export interface IWorkbenchEnvironmentService extends IEnvironmentService { readonly skipReleaseNotes: boolean; + readonly debugRenderer: boolean; + /** * @deprecated this property will go away eventually as it * duplicates many properties of the environment service diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts index a70f8a9d9d7c6..be79900909112 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts @@ -286,7 +286,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost version: this._productService.version, parentPid: -1, environment: { - isExtensionDevelopmentDebug: false, //todo@jrieken web + isExtensionDevelopmentDebug: this._environmentService.debugRenderer, appName: this._productService.nameLong, appUriScheme: this._productService.urlProtocol, appLanguage: platform.language,