diff --git a/src/extension/debugger/debugPort/portAttributesProvider.ts b/src/extension/debugger/debugPort/portAttributesProvider.ts index 13fea1b5..21737185 100644 --- a/src/extension/debugger/debugPort/portAttributesProvider.ts +++ b/src/extension/debugger/debugPort/portAttributesProvider.ts @@ -2,13 +2,34 @@ * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ -import { CancellationToken, PortAttributes, PortAttributesProvider, ProviderResult } from 'vscode'; +import { + CancellationToken, + PortAttributes, + PortAttributesProvider, + PortAutoForwardAction, + ProviderResult, +} from 'vscode'; export class DebugPortAttributesProvider implements PortAttributesProvider { + private knownPorts: number[] = []; + + public setPortAttribute(port: number): void { + if (!this.knownPorts.includes(port)) { + this.knownPorts.push(port); + } + } + + public resetPortAttribute(): void { + this.knownPorts.pop(); + } + public providePortAttributes( - _attributes: { port: number; pid?: number; commandLine?: string }, + attributes: { port: number; pid?: number; commandLine?: string }, _token: CancellationToken, ): ProviderResult { + if (this.knownPorts.includes(attributes.port)) { + return new PortAttributes(PortAutoForwardAction.Ignore); + } return undefined; } } diff --git a/src/extension/debugger/hooks/constants.ts b/src/extension/debugger/hooks/constants.ts index add0fcae..7b27a241 100644 --- a/src/extension/debugger/hooks/constants.ts +++ b/src/extension/debugger/hooks/constants.ts @@ -8,4 +8,5 @@ export enum DebuggerEvents { // Event sent by PTVSD when a child process is launched and ready to be attached to for multi-proc debugging. PtvsdAttachToSubprocess = 'ptvsd_attach', DebugpyAttachToSubprocess = 'debugpyAttach', + DebugpySockets = 'debugpySockets', } diff --git a/src/extension/debugger/hooks/debugpySocketsHandler.ts b/src/extension/debugger/hooks/debugpySocketsHandler.ts new file mode 100644 index 00000000..b777a271 --- /dev/null +++ b/src/extension/debugger/hooks/debugpySocketsHandler.ts @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +import { inject, injectable } from 'inversify'; +import { DebugSessionCustomEvent } from 'vscode'; +import { swallowExceptions } from '../../common/utils/decorators'; +import { DebuggerEvents } from './constants'; +import { DebuggerTypeName } from '../../constants'; +import { DebugPortAttributesProvider } from '../debugPort/portAttributesProvider'; +import { IDebugSessionEventHandlers } from './types'; + +/** + * This class is responsible for register ports using by debugpy in the portProvider. + * @export + * @class ChildProcessAttachEventHandler + * @implements {IDebugSessionEventHandlers} + */ +@injectable() +export class DebugpySocketsHandler implements IDebugSessionEventHandlers { + constructor( + @inject(DebugPortAttributesProvider) private readonly debugPortAttributesProvider: DebugPortAttributesProvider, + ) {} + + @swallowExceptions('Handle child process launch') + public async handleCustomEvent(event: DebugSessionCustomEvent): Promise { + if (!event || event.session.configuration.type !== DebuggerTypeName) { + return; + } + + if (event.event == DebuggerEvents.DebugpySockets) { + let portSocket = event.body.sockets.find((socket: { [x: string]: any }) => { + return socket['internal'] == false; + }); + if (portSocket != undefined) { + this.debugPortAttributesProvider.setPortAttribute(portSocket.port); + } + } else { + return; + } + } +} diff --git a/src/extension/extensionInit.ts b/src/extension/extensionInit.ts index 477e7f1d..d450de7f 100644 --- a/src/extension/extensionInit.ts +++ b/src/extension/extensionInit.ts @@ -33,6 +33,7 @@ import { ignoreErrors } from './common/promiseUtils'; import { pickArgsInput } from './common/utils/localize'; import { DebugPortAttributesProvider } from './debugger/debugPort/portAttributesProvider'; import { getConfigurationsByUri } from './debugger/configuration/launch.json/launchJsonReader'; +import { DebugpySocketsHandler } from './debugger/hooks/debugpySocketsHandler'; export async function registerDebugger(context: IExtensionContext): Promise { const childProcessAttachService = new ChildProcessAttachService(); @@ -154,4 +155,17 @@ export async function registerDebugger(context: IExtensionContext): Promise { + ignoreErrors(debugpySocketsHandler.handleCustomEvent(e)); + }), + ); + + context.subscriptions.push( + debug.onDidTerminateDebugSession(() => { + debugPortAttributesProvider.resetPortAttribute(); + }), + ); }