@@ -408,9 +408,18 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
408
408
// Generating a task is async, therefore we must *await* *all* map(task => config) Promises to resolve.
409
409
let configs : CppDebugConfiguration [ ] = [ ] ;
410
410
if ( buildTasks . length !== 0 ) {
411
- configs = await Promise . all ( buildTasks . map < Promise < CppDebugConfiguration > > ( async task => {
411
+ configs = ( await Promise . all ( buildTasks . map < Promise < CppDebugConfiguration | undefined > > ( async task => {
412
412
const definition : CppBuildTaskDefinition = task . definition as CppBuildTaskDefinition ;
413
413
const compilerPath : string = definition . command ;
414
+ // Filter out the tasks that has an invalid compiler path.
415
+ const compilerPathExists : boolean = path . isAbsolute ( compilerPath ) ?
416
+ // Absolute path, just check if it exists
417
+ await util . checkFileExists ( compilerPath ) :
418
+ // Non-absolute. Check on $PATH
419
+ ( ( await util . whichAsync ( compilerPath ) ) !== undefined ) ;
420
+ if ( ! compilerPathExists ) {
421
+ logger . getOutputChannelLogger ( ) . appendLine ( localize ( 'compiler.path.not.exists' , "Unable to find {0}. {1} task is ignored." , compilerPath , definition . label ) ) ;
422
+ }
414
423
const compilerName : string = path . basename ( compilerPath ) ;
415
424
const newConfig : CppDebugConfiguration = { ...defaultTemplateConfig } ; // Copy enumerables and properties
416
425
newConfig . existing = false ;
@@ -439,20 +448,24 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
439
448
const isCl : boolean = compilerName === "cl.exe" ;
440
449
newConfig . cwd = isWindows && ! isCl && ! process . env . PATH ?. includes ( path . dirname ( compilerPath ) ) ? path . dirname ( compilerPath ) : "${fileDirname}" ;
441
450
442
- return new Promise < CppDebugConfiguration > ( resolve => {
451
+ return new Promise < CppDebugConfiguration | undefined > ( async resolve => {
443
452
if ( platformInfo . platform === "darwin" ) {
444
453
return resolve ( newConfig ) ;
445
454
} else {
446
455
let debuggerName : string ;
447
456
if ( compilerName . startsWith ( "clang" ) ) {
448
457
newConfig . MIMode = "lldb" ;
449
- debuggerName = "lldb-mi" ;
450
- // Search for clang-8, clang-10, etc.
451
- if ( ( compilerName !== "clang-cl.exe" ) && ( compilerName !== "clang-cpp.exe" ) ) {
452
- const suffixIndex : number = compilerName . indexOf ( "-" ) ;
453
- if ( suffixIndex !== - 1 ) {
454
- const suffix : string = compilerName . substring ( suffixIndex ) ;
455
- debuggerName += suffix ;
458
+ if ( isWindows ) {
459
+ debuggerName = "lldb" ;
460
+ } else {
461
+ debuggerName = "lldb-mi" ;
462
+ // Search for clang-8, clang-10, etc.
463
+ if ( ( compilerName !== "clang-cl.exe" ) && ( compilerName !== "clang-cpp.exe" ) ) {
464
+ const suffixIndex : number = compilerName . indexOf ( "-" ) ;
465
+ if ( suffixIndex !== - 1 ) {
466
+ const suffix : string = compilerName . substring ( suffixIndex ) ;
467
+ debuggerName += suffix ;
468
+ }
456
469
}
457
470
}
458
471
newConfig . type = DebuggerType . cppdbg ;
@@ -468,22 +481,27 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
468
481
}
469
482
const compilerDirname : string = path . dirname ( compilerPath ) ;
470
483
const debuggerPath : string = path . join ( compilerDirname , debuggerName ) ;
471
- if ( isWindows ) {
484
+
485
+ // Check if debuggerPath exists.
486
+ if ( await util . checkFileExists ( debuggerPath ) ) {
472
487
newConfig . miDebuggerPath = debuggerPath ;
473
- return resolve ( newConfig ) ;
488
+ } else if ( ( await util . whichAsync ( debuggerName ) ) !== undefined ) {
489
+ // Check if debuggerName exists on $PATH
490
+ newConfig . miDebuggerPath = debuggerName ;
474
491
} else {
475
- fs . stat ( debuggerPath , ( err , stats : fs . Stats ) => {
476
- if ( ! err && stats && stats . isFile ( ) ) {
477
- newConfig . miDebuggerPath = debuggerPath ;
478
- } else {
479
- newConfig . miDebuggerPath = path . join ( "/usr" , "bin" , debuggerName ) ;
480
- }
481
- return resolve ( newConfig ) ;
482
- } ) ;
492
+ // Try the usr path for non-windows platforms.
493
+ const usrDebuggerPath : string = path . join ( "/usr" , "bin" , debuggerName ) ;
494
+ if ( ! isWindows && await util . checkFileExists ( usrDebuggerPath ) ) {
495
+ newConfig . miDebuggerPath = usrDebuggerPath ;
496
+ } else {
497
+ logger . getOutputChannelLogger ( ) . appendLine ( localize ( 'debugger.path.not.exists' , "Unable to find the {0} debugger. The debug configuration for {1} is ignored." , `\" ${ debuggerName } \"` , compilerName ) ) ;
498
+ return resolve ( undefined ) ;
499
+ }
483
500
}
501
+ return resolve ( newConfig ) ;
484
502
}
485
503
} ) ;
486
- } ) ) ;
504
+ } ) ) ) . filter ( ( item ) : item is CppDebugConfiguration => ! ! item ) ;
487
505
}
488
506
configs . push ( defaultTemplateConfig ) ;
489
507
const existingConfigs : CppDebugConfiguration [ ] | undefined = this . getLaunchConfigs ( folder , type ) ?. map ( config => {
0 commit comments