提交 dc234da0 编写于 作者: A Andre Weinand

terminate debug sessions properly

上级 aa094730
......@@ -150,6 +150,9 @@ export interface IDebugSession extends ITreeElement {
readonly state: State;
readonly root: IWorkspaceFolder;
readonly parentSession: IDebugSession | undefined;
readonly subId: string | undefined;
setSubId(subId: string | undefined): void;
getLabel(): string;
......
......@@ -135,27 +135,28 @@ export class DebugService implements IDebugService {
this.toDispose.push(this.storageService.onWillSaveState(this.saveState, this));
this.lifecycleService.onShutdown(this.dispose, this);
this.toDispose.push(this.extensionHostDebugService.onAttachSession(data => {
const session = this.model.getSession(data.id, true);
this.toDispose.push(this.extensionHostDebugService.onAttachSession(event => {
const session = this.model.getSession(event.sessionId, true);
if (session) {
// EH was started in debug mode -> attach to it
session.configuration.request = 'attach';
session.configuration.port = data.port;
session.configuration.port = event.port;
session.setSubId(event.subId);
this.launchOrAttachToSession(session).then(undefined, errors.onUnexpectedError);
}
}));
this.toDispose.push(this.extensionHostDebugService.onTerminateSession(sessionId => {
const session = this.model.getSession(sessionId);
if (session) {
this.toDispose.push(this.extensionHostDebugService.onTerminateSession(event => {
const session = this.model.getSession(event.sessionId);
if (session && session.subId === event.subId) {
session.disconnect().then(undefined, errors.onUnexpectedError);
}
}));
this.toDispose.push(this.extensionHostDebugService.onLogToSession(data => {
const session = this.model.getSession(data.id, true);
this.toDispose.push(this.extensionHostDebugService.onLogToSession(event => {
const session = this.model.getSession(event.sessionId, true);
if (session) {
// extension logged output -> show it in REPL
const sev = data.log.severity === 'warn' ? severity.Warning : data.log.severity === 'error' ? severity.Error : severity.Info;
const { args, stack } = parse(data.log);
const sev = event.log.severity === 'warn' ? severity.Warning : event.log.severity === 'error' ? severity.Error : severity.Info;
const { args, stack } = parse(event.log);
const frame = !!stack ? getFirstFrame(stack) : undefined;
session.logToRepl(sev, args, frame);
}
......
......@@ -35,7 +35,9 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { INotificationService } from 'vs/platform/notification/common/notification';
export class DebugSession implements IDebugSession {
private id: string;
private _subId: string | undefined;
private raw: RawDebugSession | undefined;
private initialized = false;
......@@ -76,6 +78,14 @@ export class DebugSession implements IDebugSession {
return this.id;
}
setSubId(subId: string | undefined) {
this._subId = subId;
}
get subId(): string | undefined {
return this._subId;
}
get configuration(): IConfig {
return this._configuration.resolved;
}
......
......@@ -124,6 +124,12 @@ export class MockDebugService implements IDebugService {
export class MockSession implements IDebugSession {
subId: string | undefined;
setSubId(subId: string | undefined): void {
throw new Error('Method not implemented.');
}
get parentSession(): IDebugSession | undefined {
return undefined;
}
......
......@@ -10,6 +10,22 @@ import { IRemoteConsoleLog } from 'vs/base/common/console';
export const IExtensionHostDebugService = createDecorator<IExtensionHostDebugService>('extensionHostDebugService');
export interface IAttachSessionEvent {
sessionId: string;
subId?: string;
port: number;
}
export interface ILogToSessionEvent {
sessionId: string;
log: IRemoteConsoleLog;
}
export interface ITerminateSessionEvent {
sessionId: string;
subId?: string;
}
export interface IExtensionHostDebugService {
_serviceBrand: any;
......@@ -19,12 +35,12 @@ export interface IExtensionHostDebugService {
close(resource: URI): void;
onClose: Event<URI>;
attachSession(id: string, port: number): void;
onAttachSession: Event<{ id: string, port: number }>;
attachSession(sessionId: string, port: number, subId?: string): void;
onAttachSession: Event<IAttachSessionEvent>;
logToSession(id: string, log: IRemoteConsoleLog): void;
onLogToSession: Event<{ id: string, log: IRemoteConsoleLog }>;
logToSession(sessionId: string, log: IRemoteConsoleLog): void;
onLogToSession: Event<ILogToSessionEvent>;
terminateSession(id: string): void;
onTerminateSession: Event<string>;
terminateSession(sessionId: string, subId?: string): void;
onTerminateSession: Event<ITerminateSessionEvent>;
}
\ No newline at end of file
......@@ -6,7 +6,7 @@
import { Event, Emitter } from 'vs/base/common/event';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IExtensionHostDebugService } from 'vs/workbench/services/extensions/common/extensionHostDebug';
import { IExtensionHostDebugService, IAttachSessionEvent, ITerminateSessionEvent, ILogToSessionEvent } from 'vs/workbench/services/extensions/common/extensionHostDebug';
import { URI } from 'vs/base/common/uri';
import { IRemoteConsoleLog } from 'vs/base/common/console';
import { ipcRenderer as ipc } from 'electron';
......@@ -16,10 +16,8 @@ interface IReloadBroadcast {
resource: string;
}
interface IAttachSessionBroadcast {
interface IAttachSessionBroadcast extends IAttachSessionEvent {
type: 'vscode:extensionAttach';
id: string;
port: number;
}
interface ICloseBroadcast {
......@@ -27,15 +25,12 @@ interface ICloseBroadcast {
resource: string;
}
interface ILogToSessionBroadcast {
interface ILogToSessionBroadcast extends ILogToSessionEvent {
type: 'vscode:extensionLog';
id: string;
log: IRemoteConsoleLog;
}
interface ITerminateSessionBroadcast {
interface ITerminateSessionBroadcast extends ITerminateSessionEvent {
type: 'vscode:extensionTerminate';
id: string;
}
const CHANNEL = 'vscode:extensionHostDebug';
......@@ -46,9 +41,9 @@ class ExtensionHostDebugService implements IExtensionHostDebugService {
private windowId: number;
private readonly _onReload = new Emitter<URI>();
private readonly _onClose = new Emitter<URI>();
private readonly _onAttachSession = new Emitter<{ id: string, port: number }>();
private readonly _onLogToSession = new Emitter<{ id: string, log: IRemoteConsoleLog }>();
private readonly _onTerminateSession = new Emitter<string>();
private readonly _onAttachSession = new Emitter<IAttachSessionEvent>();
private readonly _onLogToSession = new Emitter<ILogToSessionEvent>();
private readonly _onTerminateSession = new Emitter<ITerminateSessionEvent>();
constructor(
@IWindowService readonly windowService: IWindowService,
......@@ -56,20 +51,22 @@ class ExtensionHostDebugService implements IExtensionHostDebugService {
this.windowId = windowService.windowId;
ipc.on(CHANNEL, (_: unknown, broadcast: IReloadBroadcast | ICloseBroadcast | IAttachSessionBroadcast | ILogToSessionBroadcast | ITerminateSessionBroadcast) => {
if (broadcast.type === 'vscode:extensionReload') {
this._onReload.fire(URI.parse(broadcast.resource));
}
if (broadcast.type === 'vscode:extensionCloseExtensionHost') {
this._onClose.fire(URI.parse(broadcast.resource));
}
if (broadcast.type === 'vscode:extensionAttach') {
this._onAttachSession.fire({ id: broadcast.id, port: broadcast.port });
}
if (broadcast.type === 'vscode:extensionLog') {
this._onLogToSession.fire({ id: broadcast.id, log: broadcast.log });
}
if (broadcast.type === 'vscode:extensionTerminate') {
this._onTerminateSession.fire(broadcast.id);
switch (broadcast.type) {
case 'vscode:extensionReload':
this._onReload.fire(URI.parse(broadcast.resource));
break;
case 'vscode:extensionCloseExtensionHost':
this._onClose.fire(URI.parse(broadcast.resource));
break;
case 'vscode:extensionAttach':
this._onAttachSession.fire(broadcast);
break;
case 'vscode:extensionLog':
this._onLogToSession.fire(broadcast);
break;
case 'vscode:extensionTerminate':
this._onTerminateSession.fire(broadcast);
break;
}
});
}
......@@ -96,38 +93,40 @@ class ExtensionHostDebugService implements IExtensionHostDebugService {
return this._onClose.event;
}
attachSession(id: string, port: number): void {
attachSession(sessionId: string, port: number, subId?: string): void {
ipc.send(CHANNEL, this.windowId, <IAttachSessionBroadcast>{
type: 'vscode:extensionAttach',
id,
port
sessionId,
port,
subId
});
}
get onAttachSession(): Event<{ id: string, port: number }> {
get onAttachSession(): Event<IAttachSessionEvent> {
return this._onAttachSession.event;
}
logToSession(id: string, log: IRemoteConsoleLog): void {
logToSession(sessionId: string, log: IRemoteConsoleLog): void {
ipc.send(CHANNEL, this.windowId, <ILogToSessionBroadcast>{
type: 'vscode:extensionLog',
id,
sessionId,
log
});
}
get onLogToSession(): Event<{ id: string, log: IRemoteConsoleLog }> {
get onLogToSession(): Event<ILogToSessionEvent> {
return this._onLogToSession.event;
}
terminateSession(id: string): void {
terminateSession(sessionId: string, subId?: string): void {
ipc.send(CHANNEL, this.windowId, <ITerminateSessionBroadcast>{
type: 'vscode:extensionTerminate',
id
sessionId,
subId
});
}
get onTerminateSession(): Event<string> {
get onTerminateSession(): Event<ITerminateSessionEvent> {
return this._onTerminateSession.event;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册