Skip to content

Commit e91e3f0

Browse files
isadorasophiaIsadora Rodopoulos
andauthored
Track debugging sessions until csdevkit is initialized (#6480)
* Track debugging sessions until csdevkit is initialized. * Address code review suggestions. * Use the session parameter to untrack a session. --------- Co-authored-by: Isadora Rodopoulos <[email protected]>
1 parent 9f97603 commit e91e3f0

File tree

4 files changed

+101
-23
lines changed

4 files changed

+101
-23
lines changed

src/coreclrDebug/activate.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -310,21 +310,3 @@ export class DebugAdapterExecutableFactory implements vscode.DebugAdapterDescrip
310310
return executable;
311311
}
312312
}
313-
314-
let _brokeredServicePipeName: string | undefined;
315-
316-
/**
317-
* Initialize brokered service pipe name from C# dev kit, if available.
318-
*
319-
* @param csDevKitPipeName Activated brokered service pipe name activated by {@link CSharpDevKitExports}.
320-
*/
321-
export function initializeBrokeredServicePipeName(csDevKitPipeName: string) {
322-
_brokeredServicePipeName = csDevKitPipeName;
323-
}
324-
325-
/**
326-
* Fetch the brokered service pipe name from C# dev kit, if available.
327-
*/
328-
export function getBrokeredServicePipeName(): string | undefined {
329-
return _brokeredServicePipeName;
330-
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
8+
/**
9+
* This tracks a debug session until C# dev kit is loaded (if present) and STOPS tracking any existing
10+
* debug session after C# dev kit is loaded.
11+
* The idea is to avoid a race condition if a debugging session starts before C# dev kit is initialized,
12+
* since the brokered service pipe name will be sent with a 'launch' command.
13+
* If the extension loads during an existing session, rather than not initializing any C# dev kit services (such as hot reload),
14+
* this sends a custom request to the engine with the brokered service pipe name in order to initialize it.
15+
*/
16+
export class ProvisionalDebugSessionTracker {
17+
private _sessions: Set<vscode.DebugSession> | undefined = new Set<vscode.DebugSession>();
18+
19+
private _onDidStartDebugSession: vscode.Disposable | undefined;
20+
private _onDidTerminateDebugSession: vscode.Disposable | undefined;
21+
22+
private _brokeredServicePipeName: string | undefined;
23+
24+
/**
25+
* Initializes the debug session handlers.
26+
*/
27+
initializeDebugSessionHandlers(context: vscode.ExtensionContext): void {
28+
this._onDidStartDebugSession = vscode.debug.onDidStartDebugSession(this.onDidStartDebugSession.bind(this));
29+
30+
this._onDidTerminateDebugSession = vscode.debug.onDidTerminateDebugSession((session: vscode.DebugSession) => {
31+
this.onDidTerminateDebugSession(session);
32+
});
33+
34+
context.subscriptions.push(this._onDidStartDebugSession);
35+
context.subscriptions.push(this._onDidTerminateDebugSession);
36+
}
37+
38+
/**
39+
* Tracks a debug session until it is terminated.
40+
* @param session Debug session.
41+
*/
42+
onDidStartDebugSession(session: vscode.DebugSession): void {
43+
if (session.type !== 'coreclr') {
44+
return;
45+
}
46+
47+
this._sessions?.add(session);
48+
}
49+
50+
/**
51+
* Notifies that a debug session has been terminated.
52+
*/
53+
onDidTerminateDebugSession(session: vscode.DebugSession): void {
54+
this._sessions?.delete(session);
55+
}
56+
57+
/**
58+
* If there is any active debug session, this notifies the engine that csdevkit was loaded.
59+
* @param csDevKitPipeName Brokered service pipe name activated by {@link CSharpDevKitExports}.
60+
*/
61+
async onCsDevKitInitialized(csDevKitPipeName: string): Promise<void> {
62+
this._brokeredServicePipeName = csDevKitPipeName;
63+
64+
const sessions = this._sessions;
65+
if (sessions != undefined) {
66+
// Debugging session already started, send a custom DAP request to the engine.
67+
sessions.forEach((s) => s.customRequest('initializeBrokeredServicePipeName', csDevKitPipeName));
68+
}
69+
70+
// Since C# dev kit was initialized, we no longer need to track debugging sessions.
71+
this.cleanup();
72+
}
73+
74+
/**
75+
* Fetches the brokered service pipe name from C# dev kit, if available.
76+
*/
77+
getBrokeredServicePipeName(): string | undefined {
78+
return this._brokeredServicePipeName;
79+
}
80+
81+
/**
82+
* No longer tracks any debugging session going forward.
83+
*/
84+
cleanup(): void {
85+
this._sessions?.clear();
86+
this._sessions = undefined;
87+
88+
this._onDidStartDebugSession?.dispose();
89+
this._onDidTerminateDebugSession?.dispose();
90+
}
91+
}
92+
93+
export const debugSessionTracker = new ProvisionalDebugSessionTracker();

src/main.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import { ServerStateChange } from './lsptoolshost/serverStateChange';
5757
import { SolutionSnapshotProvider } from './lsptoolshost/services/solutionSnapshotProvider';
5858
import { RazorTelemetryDownloader } from './razor/razorTelemetryDownloader';
5959
import { commonOptions, omnisharpOptions, razorOptions } from './shared/options';
60+
import { debugSessionTracker } from './coreclrDebug/provisionalDebugSessionTracker';
6061

6162
export async function activate(
6263
context: vscode.ExtensionContext
@@ -335,6 +336,8 @@ export async function activate(
335336
reporter.sendTelemetryEvent('CSharpActivated', activationProperties);
336337

337338
if (!useOmnisharpServer) {
339+
debugSessionTracker.initializeDebugSessionHandlers(context);
340+
338341
tryGetCSharpDevKitExtensionExports(csharpLogObserver);
339342

340343
// If we got here, the server should definitely have been created.
@@ -401,9 +404,9 @@ function tryGetCSharpDevKitExtensionExports(csharpLogObserver: CsharpLoggerObser
401404
]);
402405

403406
// Notify the vsdbg configuration provider that C# dev kit has been loaded.
404-
exports.serverProcessLoaded(async () =>
405-
coreclrdebug.initializeBrokeredServicePipeName(await exports.getBrokeredServiceServerPipeName())
406-
);
407+
exports.serverProcessLoaded(async () => {
408+
debugSessionTracker.onCsDevKitInitialized(await exports.getBrokeredServiceServerPipeName());
409+
});
407410

408411
vscode.commands.executeCommand('setContext', 'dotnet.debug.serviceBrokerAvailable', true);
409412
} else {

src/shared/configurationProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as vscode from 'vscode';
77
import { ParsedEnvironmentFile } from '../coreclrDebug/parsedEnvironmentFile';
8-
import { getBrokeredServicePipeName } from '../coreclrDebug/activate';
8+
import { debugSessionTracker } from '../coreclrDebug/provisionalDebugSessionTracker';
99

1010
import { MessageItem } from '../vscodeAdapter';
1111
import { CertToolStatusCodes, createSelfSignedCert, hasDotnetDevCertsHttps } from '../utils/dotnetDevCertsHttps';
@@ -66,7 +66,7 @@ export class BaseVsDbgConfigurationProvider implements vscode.DebugConfiguration
6666
return null;
6767
}
6868

69-
const brokeredServicePipeName = getBrokeredServicePipeName();
69+
const brokeredServicePipeName = debugSessionTracker.getBrokeredServicePipeName();
7070
if (brokeredServicePipeName !== undefined) {
7171
debugConfiguration.brokeredServicePipeName = brokeredServicePipeName;
7272
}

0 commit comments

Comments
 (0)