protected async stackTraceRequest()

in src/debugAdapter/goDebug.ts [1448:1514]


	protected async stackTraceRequest(
		response: DebugProtocol.StackTraceResponse,
		args: DebugProtocol.StackTraceArguments
	): Promise<void> {
		log('StackTraceRequest');
		// For normal VSCode, this request doesn't get invoked when we send a Dummy thread
		// in the scenario where the debuggee is running.
		// For Theia, however, this does get invoked and so we should just send an error
		// response that we cannot get the stack trace at this point since the debugggee is running.
		if (await this.isDebuggeeRunning()) {
			this.sendErrorResponse(response, 2004, 'Unable to produce stack trace as the debugger is running');
			return;
		}

		// delve does not support frame paging, so we ask for a large depth
		const goroutineId = args.threadId;
		const stackTraceIn = { id: goroutineId, depth: this.delve?.stackTraceDepth };
		if (!this.delve?.isApiV1) {
			Object.assign(stackTraceIn, { full: false, cfg: this.delve?.loadConfig });
		}
		this.delve?.call<DebugLocation[] | StacktraceOut>(
			this.delve?.isApiV1 ? 'StacktraceGoroutine' : 'Stacktrace',
			[stackTraceIn],
			async (err, out) => {
				if (err) {
					this.logDelveError(err, 'Failed to produce stacktrace');
					return this.sendErrorResponse(
						response,
						2004,
						'Unable to produce stack trace: "{e}"',
						{ e: err.toString() },
						// Disable showUser pop-up since errors already show up under the CALL STACK pane
						undefined
					);
				}
				const locations = this.delve?.isApiV1 ? <DebugLocation[]>out : (<StacktraceOut>out).Locations;
				log('locations', locations);

				if (this.delve?.isRemoteDebugging) {
					await this.initializeRemotePackagesAndSources();
				}

				let stackFrames = locations.map((location, frameId) => {
					const uniqueStackFrameId = this.stackFrameHandles.create([goroutineId, frameId]);
					return new StackFrame(
						uniqueStackFrameId,
						location.function ? location.function.name : '<unknown>',
						location.file === '<autogenerated>'
							? undefined
							: new Source(path.basename(location.file), this.toLocalPath(location.file)),
						location.line,
						0
					);
				});
				const { startFrame = 0, levels = 0 } = args;
				if (startFrame > 0) {
					stackFrames = stackFrames.slice(startFrame);
				}
				if (levels > 0) {
					stackFrames = stackFrames.slice(0, levels);
				}
				response.body = { stackFrames, totalFrames: locations.length };
				this.sendResponse(response);
				log('StackTraceResponse');
			}
		);
	}