in src/vs/workbench/contrib/debug/browser/debugService.ts [267:365]
async startDebugging(launch: ILaunch | undefined, configOrName?: IConfig | string, options?: IDebugSessionOptions): Promise<boolean> {
this.startInitializingState();
try {
// make sure to save all files and that the configuration is up to date
await this.extensionService.activateByEvent('onDebug');
await this.editorService.saveAll();
await this.configurationService.reloadConfiguration(launch ? launch.workspace : undefined);
await this.extensionService.whenInstalledExtensionsRegistered();
let config: IConfig | undefined;
let compound: ICompound | undefined;
if (!configOrName) {
configOrName = this.configurationManager.selectedConfiguration.name;
}
if (typeof configOrName === 'string' && launch) {
config = launch.getConfiguration(configOrName);
compound = launch.getCompound(configOrName);
const sessions = this.model.getSessions();
const alreadyRunningMessage = nls.localize('configurationAlreadyRunning', "There is already a debug configuration \"{0}\" running.", configOrName);
if (sessions.some(s => s.configuration.name === configOrName && (!launch || !launch.workspace || !s.root || s.root.uri.toString() === launch.workspace.uri.toString()))) {
throw new Error(alreadyRunningMessage);
}
if (compound && compound.configurations && sessions.some(p => compound!.configurations.indexOf(p.configuration.name) !== -1)) {
throw new Error(alreadyRunningMessage);
}
} else if (typeof configOrName !== 'string') {
config = configOrName;
}
if (compound) {
// we are starting a compound debug, first do some error checking and than start each configuration in the compound
if (!compound.configurations) {
throw new Error(nls.localize({ key: 'compoundMustHaveConfigurations', comment: ['compound indicates a "compounds" configuration item', '"configurations" is an attribute and should not be localized'] },
"Compound must have \"configurations\" attribute set in order to start multiple configurations."));
}
if (compound.preLaunchTask) {
const taskResult = await this.taskRunner.runTaskAndCheckErrors(launch?.workspace || this.contextService.getWorkspace(), compound.preLaunchTask, (msg, actions) => this.showError(msg, actions));
if (taskResult === TaskRunResult.Failure) {
this.endInitializingState();
return false;
}
}
if (compound.stopAll) {
options = { ...options, compoundRoot: new DebugCompoundRoot() };
}
const values = await Promise.all(compound.configurations.map(configData => {
const name = typeof configData === 'string' ? configData : configData.name;
if (name === compound!.name) {
return Promise.resolve(false);
}
let launchForName: ILaunch | undefined;
if (typeof configData === 'string') {
const launchesContainingName = this.configurationManager.getLaunches().filter(l => !!l.getConfiguration(name));
if (launchesContainingName.length === 1) {
launchForName = launchesContainingName[0];
} else if (launch && launchesContainingName.length > 1 && launchesContainingName.indexOf(launch) >= 0) {
// If there are multiple launches containing the configuration give priority to the configuration in the current launch
launchForName = launch;
} else {
throw new Error(launchesContainingName.length === 0 ? nls.localize('noConfigurationNameInWorkspace', "Could not find launch configuration '{0}' in the workspace.", name)
: nls.localize('multipleConfigurationNamesInWorkspace', "There are multiple launch configurations '{0}' in the workspace. Use folder name to qualify the configuration.", name));
}
} else if (configData.folder) {
const launchesMatchingConfigData = this.configurationManager.getLaunches().filter(l => l.workspace && l.workspace.name === configData.folder && !!l.getConfiguration(configData.name));
if (launchesMatchingConfigData.length === 1) {
launchForName = launchesMatchingConfigData[0];
} else {
throw new Error(nls.localize('noFolderWithName', "Can not find folder with name '{0}' for configuration '{1}' in compound '{2}'.", configData.folder, configData.name, compound!.name));
}
}
return this.createSession(launchForName, launchForName!.getConfiguration(name), options);
}));
const result = values.every(success => !!success); // Compound launch is a success only if each configuration launched successfully
this.endInitializingState();
return result;
}
if (configOrName && !config) {
const message = !!launch ? nls.localize('configMissing', "Configuration '{0}' is missing in 'launch.json'.", typeof configOrName === 'string' ? configOrName : configOrName.name) :
nls.localize('launchJsonDoesNotExist', "'launch.json' does not exist for passed workspace folder.");
throw new Error(message);
}
const result = await this.createSession(launch, config, options);
this.endInitializingState();
return result;
} catch (err) {
// make sure to get out of initializing state, and propagate the result
this.notificationService.error(err);
this.endInitializingState();
return Promise.reject(err);
}
}