Repository: microsoft/vscode (TypeScript)
Date: 2022-11-01 18:02:27+00:00
Task type: Bug Fix

Issue:
UI doesn't indicate each thread listed in the call stack as having been "PAUSED ON EXCEPTION" on loading core dump
**Version of VS Code:** 1.67.2

**OS:** Ubuntu 18.04.6 LTS

**Reproducible steps that cause the issue:**

Have Visual Studio Code load a core dump in _lldb_ via _lldb-vscode_ (debug adapter for Visual Studio Code available as part of the LLDB project, which, to the best of my knowledge, is unpublished) by employing an attach configuration akin to the following –

```
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Post-mortem Debug",
            "type": "lldb-vscode",
            "request": "attach",
            "program": "${workspaceFolder}/a.out",
            "coreFile": "${workspaceFolder}/a.out.core"
        }
    ]
}
```

**What I expect to see, versus what I actually see:**

All threads in the process are stopped with reason _exception_ –

```
...

{"body":{"allThreadsStopped":true,"preserveFocusHint":false,"reason":"exception","threadCausedFocus":true,"threadId":848},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":843},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":844},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":845},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":846},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":847},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":849},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":850},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":851},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":852},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":853},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":854},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":855},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":856},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1881},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1882},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1883},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1884},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1886},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1887},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1888},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1889},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":true,"preserveFocusHint":true,"reason":"exception","threadId":1890},"event":"stopped","seq":0,"type":"event"}

...
```

So, I'd expect the UI to indicate each thread listed in the call stack as having been _PAUSED ON EXCEPTION_. However, I see that the UI indicates only _Thread # 23_ as having been _PAUSED ON EXCEPTION_, and others as having been _PAUSED_ –

![AllThreadsStoppedTrue](https://user-images.githubusercontent.com/12513869/198950367-f0095d68-c79a-4ca7-8627-8014186197b7.JPG)

What's curious, though, is that if _allThreadsStopped_ is reported as _false_ in each of the pertinent stopped events, then the UI indicates all threads in the call stack as having been _PAUSED ON EXCEPTION_ –

```
...

{"body":{"allThreadsStopped":false,"preserveFocusHint":false,"reason":"exception","threadCausedFocus":true,"threadId":848},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":843},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":844},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":845},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":846},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":847},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":849},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":850},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":851},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":852},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":853},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":854},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":855},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":856},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1881},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1882},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1883},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1884},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1886},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1887},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1888},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1889},"event":"stopped","seq":0,"type":"event"}

{"body":{"allThreadsStopped":false,"preserveFocusHint":true,"reason":"exception","threadId":1890},"event":"stopped","seq":0,"type":"event"}

...
```

![AllThreadsStoppedFalse](https://user-images.githubusercontent.com/12513869/198950594-48262c87-a9ec-494f-8509-cd7b25690e18.JPG)

Kindly let me know in case any additional information is required.


Issue discussion:
Initial investigation shows that this is from https://github.com/microsoft/vscode/blob/a803dc359aa1ed48c7acf074dd81d6af1525c8c8/src/vs/workbench/contrib/debug/browser/debugSession.ts#L892

I think it essentially clears the previous pause reason when processing the `allThreadsStopped`. I think this could keep the previous `stoppedDetails` on the thread. But, isn't it odd to send `allThreadsStopped` if you are going to send individual stopped events for every thread anyway?

Kinda related to https://github.com/microsoft/vscode/issues/70107
@roblourens, I imagine that that's an implication of the design. Currently, LLDB supports only process-centric debugging. So, when any thread in a process stops, all the other threads are stopped too. I reckon that that's why _lldb-vscode_ reports _allThreadsStopped_ as _true_ for every stopped event. However, AFAICT, _lldb-vscode_ maintains neither a list nor the states of the processes and threads under debug, and relies on pertinent events broadcast by LLDB to report stopped events. Now, if I'm not wrong, then all the threads in a core dump are stopped. So, I'd expect LLDB to broadcast a pertinent event for each thread in a core dump, and _lldb-vscode_ to consequently report stopped events for all the threads.
Sure, that's fine. Seems correct for vscode to support this the way you're using it.
@roblourens, thanks! 😁

BTW, is it too early for any work on this to be planned for a specific release? I only ask so that I can offer our customers a ballpark estimate of when they can expect the fix for this to become available. 😬

Solution patch:
diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts
--- a/src/vs/workbench/contrib/debug/browser/debugSession.ts
+++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts
@@ -889,7 +889,7 @@ export class DebugSession implements IDebugSession {
 			// whether the thread is stopped or not
 			if (stoppedDetails.allThreadsStopped) {
 				this.threads.forEach(thread => {
-					thread.stoppedDetails = thread.threadId === stoppedDetails.threadId ? stoppedDetails : { reason: undefined };
+					thread.stoppedDetails = thread.threadId === stoppedDetails.threadId ? stoppedDetails : { reason: thread.stoppedDetails?.reason };
 					thread.stopped = true;
 					thread.clearCallStack();
 				});


Test patch:
diff --git a/src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts b/src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts
--- a/src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts
+++ b/src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts
@@ -11,7 +11,7 @@ import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlighte
 import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
 import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
 import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
-import { createMockSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
+import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
 import { isStatusbarInDebugMode } from 'vs/workbench/contrib/debug/browser/statusbarColorProvider';
 import { State } from 'vs/workbench/contrib/debug/common/debug';
 import { isWindows } from 'vs/base/common/platform';
@@ -132,8 +132,8 @@ suite('Debug - Base Debug View', () => {
 
 	test('statusbar in debug mode', () => {
 		const model = createMockDebugModel();
-		const session = createMockSession(model);
-		const session2 = createMockSession(model, undefined, { suppressDebugStatusbar: true });
+		const session = createTestSession(model);
+		const session2 = createTestSession(model, undefined, { suppressDebugStatusbar: true });
 		assert.strictEqual(isStatusbarInDebugMode(State.Inactive, []), false);
 		assert.strictEqual(isStatusbarInDebugMode(State.Initializing, [session]), false);
 		assert.strictEqual(isStatusbarInDebugMode(State.Running, [session]), true);
diff --git a/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts b/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts
--- a/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts
+++ b/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts
@@ -14,7 +14,7 @@ import { createBreakpointDecorations } from 'vs/workbench/contrib/debug/browser/
 import { OverviewRulerLane } from 'vs/editor/common/model';
 import { MarkdownString } from 'vs/base/common/htmlContent';
 import { createTextModel } from 'vs/editor/test/common/testTextModel';
-import { createMockSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
+import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
 import { createMockDebugModel, MockDebugService } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
 import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
 import { ILanguageService } from 'vs/editor/common/languages/language';
@@ -174,7 +174,7 @@ suite('Debug - Breakpoints', () => {
 		const modelUri = uri.file('/myfolder/myfile.js');
 		addBreakpointsAndCheckEvents(model, modelUri, [{ lineNumber: 5, enabled: true, condition: 'x > 5' }, { lineNumber: 10, enabled: false }]);
 		const breakpoints = model.getBreakpoints();
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		const data = new Map<string, DebugProtocol.Breakpoint>();
 
 		assert.strictEqual(breakpoints[0].lineNumber, 5);
@@ -186,7 +186,7 @@ suite('Debug - Breakpoints', () => {
 		assert.strictEqual(breakpoints[0].lineNumber, 5);
 		assert.strictEqual(breakpoints[1].lineNumber, 50);
 
-		const session2 = createMockSession(model);
+		const session2 = createTestSession(model);
 		const data2 = new Map<string, DebugProtocol.Breakpoint>();
 		data2.set(breakpoints[0].getId(), { verified: true, line: 100 });
 		data2.set(breakpoints[1].getId(), { verified: true, line: 500 });
diff --git a/src/vs/workbench/contrib/debug/test/browser/callStack.test.ts b/src/vs/workbench/contrib/debug/test/browser/callStack.test.ts
--- a/src/vs/workbench/contrib/debug/test/browser/callStack.test.ts
+++ b/src/vs/workbench/contrib/debug/test/browser/callStack.test.ts
@@ -29,7 +29,7 @@ const mockWorkspaceContextService = {
 	}
 } as any;
 
-export function createMockSession(model: DebugModel, name = 'mockSession', options?: IDebugSessionOptions): DebugSession {
+export function createTestSession(model: DebugModel, name = 'mockSession', options?: IDebugSessionOptions): DebugSession {
 	return new DebugSession(generateUuid(), { resolved: { name, type: 'node', request: 'launch' }, unresolved: undefined }, undefined!, model, options, {
 		getViewModel(): any {
 			return {
@@ -79,7 +79,7 @@ suite('Debug - CallStack', () => {
 	test('threads simple', () => {
 		const threadId = 1;
 		const threadName = 'firstThread';
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		model.addSession(session);
 
 		assert.strictEqual(model.getSessions(true).length, 1);
@@ -98,7 +98,7 @@ suite('Debug - CallStack', () => {
 		assert.strictEqual(model.getSessions(true).length, 1);
 	});
 
-	test('threads multiple wtih allThreadsStopped', async () => {
+	test('threads multiple with allThreadsStopped', async () => {
 		const threadId1 = 1;
 		const threadName1 = 'firstThread';
 		const threadId2 = 2;
@@ -106,7 +106,7 @@ suite('Debug - CallStack', () => {
 		const stoppedReason = 'breakpoint';
 
 		// Add the threads
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		model.addSession(session);
 
 		session['raw'] = <any>rawSession;
@@ -178,7 +178,60 @@ suite('Debug - CallStack', () => {
 		assert.strictEqual(session.getAllThreads().length, 0);
 	});
 
-	test('threads mutltiple without allThreadsStopped', async () => {
+	test('allThreadsStopped in multiple events', async () => {
+		const threadId1 = 1;
+		const threadName1 = 'firstThread';
+		const threadId2 = 2;
+		const threadName2 = 'secondThread';
+		const stoppedReason = 'breakpoint';
+
+		// Add the threads
+		const session = createTestSession(model);
+		model.addSession(session);
+
+		session['raw'] = <any>rawSession;
+
+		// Stopped event with all threads stopped
+		model.rawUpdate({
+			sessionId: session.getId(),
+			threads: [{
+				id: threadId1,
+				name: threadName1
+			}, {
+				id: threadId2,
+				name: threadName2
+			}],
+			stoppedDetails: {
+				reason: stoppedReason,
+				threadId: threadId1,
+				allThreadsStopped: true
+			},
+		});
+
+		model.rawUpdate({
+			sessionId: session.getId(),
+			threads: [{
+				id: threadId1,
+				name: threadName1
+			}, {
+				id: threadId2,
+				name: threadName2
+			}],
+			stoppedDetails: {
+				reason: stoppedReason,
+				threadId: threadId2,
+				allThreadsStopped: true
+			},
+		});
+
+		const thread1 = session.getThread(threadId1)!;
+		const thread2 = session.getThread(threadId2)!;
+
+		assert.strictEqual(thread1.stoppedDetails?.reason, stoppedReason);
+		assert.strictEqual(thread2.stoppedDetails?.reason, stoppedReason);
+	});
+
+	test('threads multiple without allThreadsStopped', async () => {
 		const sessionStub = sinon.spy(rawSession, 'stackTrace');
 
 		const stoppedThreadId = 1;
@@ -186,7 +239,7 @@ suite('Debug - CallStack', () => {
 		const runningThreadId = 2;
 		const runningThreadName = 'runningThread';
 		const stoppedReason = 'breakpoint';
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		model.addSession(session);
 
 		session['raw'] = <any>rawSession;
@@ -258,7 +311,7 @@ suite('Debug - CallStack', () => {
 	});
 
 	test('stack frame get specific source name', () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		model.addSession(session);
 		const { firstStackFrame, secondStackFrame } = createTwoStackFrames(session);
 
@@ -267,7 +320,7 @@ suite('Debug - CallStack', () => {
 	});
 
 	test('stack frame toString()', () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		const thread = new Thread(session, 'mockthread', 1);
 		const firstSource = new Source({
 			name: 'internalModule.js',
@@ -283,17 +336,17 @@ suite('Debug - CallStack', () => {
 	});
 
 	test('debug child sessions are added in correct order', () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		model.addSession(session);
-		const secondSession = createMockSession(model, 'mockSession2');
+		const secondSession = createTestSession(model, 'mockSession2');
 		model.addSession(secondSession);
-		const firstChild = createMockSession(model, 'firstChild', { parentSession: session });
+		const firstChild = createTestSession(model, 'firstChild', { parentSession: session });
 		model.addSession(firstChild);
-		const secondChild = createMockSession(model, 'secondChild', { parentSession: session });
+		const secondChild = createTestSession(model, 'secondChild', { parentSession: session });
 		model.addSession(secondChild);
-		const thirdSession = createMockSession(model, 'mockSession3');
+		const thirdSession = createTestSession(model, 'mockSession3');
 		model.addSession(thirdSession);
-		const anotherChild = createMockSession(model, 'secondChild', { parentSession: secondSession });
+		const anotherChild = createTestSession(model, 'secondChild', { parentSession: secondSession });
 		model.addSession(anotherChild);
 
 		const sessions = model.getSessions();
@@ -306,7 +359,7 @@ suite('Debug - CallStack', () => {
 	});
 
 	test('decorations', () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		model.addSession(session);
 		const { firstStackFrame, secondStackFrame } = createTwoStackFrames(session);
 		let decorations = createDecorationsForStackFrame(firstStackFrame, true, false);
@@ -338,7 +391,7 @@ suite('Debug - CallStack', () => {
 	});
 
 	test('contexts', () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		model.addSession(session);
 		const { firstStackFrame, secondStackFrame } = createTwoStackFrames(session);
 		let context = getContext(firstStackFrame);
@@ -378,7 +431,7 @@ suite('Debug - CallStack', () => {
 			}
 		}(generateUuid(), { resolved: { name: 'stoppedSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined!, model, undefined, undefined!, undefined!, undefined!, undefined!, undefined!, mockWorkspaceContextService, undefined!, undefined!, undefined!, mockUriIdentityService, new TestInstantiationService(), undefined!, undefined!);
 
-		const runningSession = createMockSession(model);
+		const runningSession = createTestSession(model);
 		model.addSession(runningSession);
 		model.addSession(session);
 
diff --git a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts
--- a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts
+++ b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts
@@ -16,7 +16,7 @@ import { ansiColorMap } from 'vs/workbench/contrib/terminal/common/terminalColor
 import { DebugModel } from 'vs/workbench/contrib/debug/common/debugModel';
 import { DebugSession } from 'vs/workbench/contrib/debug/browser/debugSession';
 import { createMockDebugModel } from 'vs/workbench/contrib/debug/test/browser/mockDebug';
-import { createMockSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
+import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
 import { DisposableStore } from 'vs/base/common/lifecycle';
 
 suite('Debug - ANSI Handling', () => {
@@ -33,7 +33,7 @@ suite('Debug - ANSI Handling', () => {
 	setup(() => {
 		disposables = new DisposableStore();
 		model = createMockDebugModel();
-		session = createMockSession(model);
+		session = createTestSession(model);
 
 		const instantiationService: TestInstantiationService = <TestInstantiationService>workbenchInstantiationService(undefined, disposables);
 		linkDetector = instantiationService.createInstance(LinkDetector);
diff --git a/src/vs/workbench/contrib/debug/test/browser/debugHover.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugHover.test.ts
--- a/src/vs/workbench/contrib/debug/test/browser/debugHover.test.ts
+++ b/src/vs/workbench/contrib/debug/test/browser/debugHover.test.ts
@@ -5,7 +5,7 @@
 
 import * as assert from 'assert';
 import { findExpressionInStackFrame } from 'vs/workbench/contrib/debug/browser/debugHover';
-import { createMockSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
+import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
 import { StackFrame, Thread, Scope, Variable } from 'vs/workbench/contrib/debug/common/debugModel';
 import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
 import type { IScope, IExpression } from 'vs/workbench/contrib/debug/common/debug';
@@ -14,7 +14,7 @@ import { createMockDebugModel, mockUriIdentityService } from 'vs/workbench/contr
 suite('Debug - Hover', () => {
 	test('find expression in stack frame', async () => {
 		const model = createMockDebugModel();
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 
 		const thread = new class extends Thread {
 			public override getCallStack(): StackFrame[] {
diff --git a/src/vs/workbench/contrib/debug/test/browser/repl.test.ts b/src/vs/workbench/contrib/debug/test/browser/repl.test.ts
--- a/src/vs/workbench/contrib/debug/test/browser/repl.test.ts
+++ b/src/vs/workbench/contrib/debug/test/browser/repl.test.ts
@@ -11,7 +11,7 @@ import { MockRawSession, MockDebugAdapter, createMockDebugModel } from 'vs/workb
 import { SimpleReplElement, RawObjectReplElement, ReplEvaluationInput, ReplModel, ReplEvaluationResult, ReplGroup } from 'vs/workbench/contrib/debug/common/replModel';
 import { RawDebugSession } from 'vs/workbench/contrib/debug/browser/rawDebugSession';
 import { timeout } from 'vs/base/common/async';
-import { createMockSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
+import { createTestSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
 import { ReplFilter } from 'vs/workbench/contrib/debug/browser/replFilter';
 import { TreeVisibility } from 'vs/base/browser/ui/tree/tree';
 import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
@@ -27,7 +27,7 @@ suite('Debug - REPL', () => {
 	});
 
 	test('repl output', () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		const repl = new ReplModel(configurationService);
 		repl.appendToRepl(session, 'first line\n', severity.Error);
 		repl.appendToRepl(session, 'second line ', severity.Error);
@@ -85,7 +85,7 @@ suite('Debug - REPL', () => {
 	});
 
 	test('repl output count', () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		const repl = new ReplModel(configurationService);
 		repl.appendToRepl(session, 'first line\n', severity.Info);
 		repl.appendToRepl(session, 'first line\n', severity.Info);
@@ -107,11 +107,11 @@ suite('Debug - REPL', () => {
 
 	test('repl merging', () => {
 		// 'mergeWithParent' should be ignored when there is no parent.
-		const parent = createMockSession(model, 'parent', { repl: 'mergeWithParent' });
-		const child1 = createMockSession(model, 'child1', { parentSession: parent, repl: 'separate' });
-		const child2 = createMockSession(model, 'child2', { parentSession: parent, repl: 'mergeWithParent' });
-		const grandChild = createMockSession(model, 'grandChild', { parentSession: child2, repl: 'mergeWithParent' });
-		const child3 = createMockSession(model, 'child3', { parentSession: parent });
+		const parent = createTestSession(model, 'parent', { repl: 'mergeWithParent' });
+		const child1 = createTestSession(model, 'child1', { parentSession: parent, repl: 'separate' });
+		const child2 = createTestSession(model, 'child2', { parentSession: parent, repl: 'mergeWithParent' });
+		const grandChild = createTestSession(model, 'grandChild', { parentSession: child2, repl: 'mergeWithParent' });
+		const child3 = createTestSession(model, 'child3', { parentSession: parent });
 
 		let parentChanges = 0;
 		parent.onDidChangeReplElements(() => ++parentChanges);
@@ -150,7 +150,7 @@ suite('Debug - REPL', () => {
 	});
 
 	test('repl expressions', () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		assert.strictEqual(session.getReplElements().length, 0);
 		model.addSession(session);
 
@@ -172,7 +172,7 @@ suite('Debug - REPL', () => {
 	});
 
 	test('repl ordering', async () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		model.addSession(session);
 
 		const adapter = new MockDebugAdapter();
@@ -194,7 +194,7 @@ suite('Debug - REPL', () => {
 	});
 
 	test('repl groups', async () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		const repl = new ReplModel(configurationService);
 
 		repl.appendToRepl(session, 'first global line', severity.Info);
@@ -232,7 +232,7 @@ suite('Debug - REPL', () => {
 	});
 
 	test('repl filter', async () => {
-		const session = createMockSession(model);
+		const session = createTestSession(model);
 		const repl = new ReplModel(configurationService);
 		const replFilter = new ReplFilter();