Skip to content

Commit 1318cce

Browse files
authored
Adding snippet to fix pipeProgram in pipeTransport (#1829)
* Adding snippet to fix pipeProgram in pipeTransport Now with VSCode 64 bit, WSL users need to use the correct pipeProgram in the correct folder. We will attempt to help users with this. * Fix tslint issue * Remove 64 bit check and check for relative path
1 parent 308e5a5 commit 1318cce

File tree

4 files changed

+113
-5
lines changed

4 files changed

+113
-5
lines changed

Extension/src/Debugger/attachToProcess.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
* See 'LICENSE' in the project root for license information.
44
* ------------------------------------------------------------------------------------------ */
55

6-
import * as vscode from 'vscode';
76
import { execChildProcess } from '../common';
87
import { PsProcessParser } from './nativeAttach';
8+
9+
import * as debugUtils from './utils';
10+
import * as fs from 'fs';
11+
import * as os from 'os';
12+
import * as path from 'path';
913
import * as util from '../common';
14+
import * as vscode from 'vscode';
1015

1116
export interface AttachItem extends vscode.QuickPickItem {
1217
id: string;
@@ -49,20 +54,47 @@ export class RemoteAttachPicker {
4954

5055
private _channel: vscode.OutputChannel = null;
5156

52-
public ShowAttachEntries(args: any): Promise<string> {
57+
public ShowAttachEntries(config: any): Promise<string> {
5358
return util.isExtensionReady().then(ready => {
5459
if (!ready) {
5560
util.displayExtensionNotReadyPrompt();
5661
} else {
5762
this._channel.clear();
5863

59-
let pipeTransport: any = args ? args.pipeTransport : null;
64+
let pipeTransport: any = config ? config.pipeTransport : null;
6065

6166
if (pipeTransport === null) {
6267
return Promise.reject<string>(new Error("Chosen debug configuration does not contain pipeTransport"));
6368
}
6469

65-
let pipeProgram: string = pipeTransport.pipeProgram;
70+
let pipeProgram: string = null;
71+
72+
if (os.platform() === 'win32' &&
73+
pipeTransport.pipeProgram &&
74+
!fs.existsSync(pipeTransport.pipeProgram)) {
75+
const pipeProgramStr: string = pipeTransport.pipeProgram.toLowerCase().trim();
76+
const expectedArch: debugUtils.ArchType = debugUtils.ArchType[process.arch];
77+
78+
// Check for pipeProgram
79+
if (!fs.existsSync(config.pipeTransport.pipeProgram)) {
80+
pipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(pipeProgramStr, expectedArch);
81+
}
82+
83+
// If pipeProgram does not get replaced and there is a pipeCwd, concatenate with pipeProgramStr and attempt to replace.
84+
if (!pipeProgram && config.pipeTransport.pipeCwd) {
85+
const pipeCwdStr: string = config.pipeTransport.pipeCwd.toLowerCase().trim();
86+
const newPipeProgramStr: string = path.join(pipeCwdStr, pipeProgramStr);
87+
88+
if (!fs.existsSync(newPipeProgramStr)) {
89+
pipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(newPipeProgramStr, expectedArch);
90+
}
91+
}
92+
}
93+
94+
if (!pipeProgram) {
95+
pipeProgram = pipeTransport.pipeProgram;
96+
}
97+
6698
let pipeArgs: string[] = pipeTransport.pipeArgs;
6799

68100
let argList: string = RemoteAttachPicker.createArgumentList(pipeArgs);

Extension/src/Debugger/configurationProvider.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
* See 'LICENSE' in the project root for license information.
44
* ------------------------------------------------------------------------------------------ */
55

6+
import * as debugUtils from './utils';
67
import * as os from 'os';
8+
import * as path from 'path';
79
import * as vscode from 'vscode';
10+
811
import { IConfiguration, IConfigurationSnippet, DebuggerType, MIConfigurations, WindowsConfigurations, WSLConfigurations, PipeTransportConfigurations } from './configurations';
912
import { parse } from 'jsonc-parser';
1013

@@ -34,6 +37,29 @@ abstract class CppConfigurationProvider implements vscode.DebugConfigurationProv
3437
return undefined;
3538
}
3639

40+
// Modify WSL config for OpenDebugAD7
41+
if (os.platform() === 'win32' &&
42+
config.pipeTransport &&
43+
config.pipeTransport.pipeProgram) {
44+
let replacedPipeProgram: string = null;
45+
const pipeProgramStr: string = config.pipeTransport.pipeProgram.toLowerCase().trim();
46+
47+
// OpenDebugAD7 is a 32-bit process. Make sure the WSL pipe transport is using the correct program.
48+
replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(pipeProgramStr, debugUtils.ArchType.ia32);
49+
50+
// If pipeProgram does not get replaced and there is a pipeCwd, concatenate with pipeProgramStr and attempt to replace.
51+
if (!replacedPipeProgram && !path.isAbsolute(pipeProgramStr) && config.pipeTransport.pipeCwd) {
52+
const pipeCwdStr: string = config.pipeTransport.pipeCwd.toLowerCase().trim();
53+
const newPipeProgramStr: string = path.join(pipeCwdStr, pipeProgramStr);
54+
55+
replacedPipeProgram = debugUtils.ArchitectureReplacer.checkAndReplaceWSLPipeProgram(newPipeProgramStr, debugUtils.ArchType.ia32);
56+
}
57+
58+
if (replacedPipeProgram) {
59+
config.pipeTransport.pipeProgram = replacedPipeProgram;
60+
}
61+
}
62+
3763
return config;
3864
}
3965
}

Extension/src/Debugger/configurations.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ export class WindowsConfigurations extends Configuration {
218218
}
219219

220220
export class WSLConfigurations extends Configuration {
221-
public bashPipeProgram = "C:\\\\Windows\\\\sysnative\\\\bash.exe";
221+
// Detects if the current VSCode is 32-bit and uses the correct bash.exe
222+
public bashPipeProgram = process.arch === 'ia32' ? "${env:windir}\\\\sysnative\\\\bash.exe" : "${env:windir}\\\\system32\\\\bash.exe";
222223

223224
public GetLaunchConfiguration(): IConfigurationSnippet {
224225
let name: string = `(${this.MIMode}) Bash on Windows Launch`;

Extension/src/Debugger/utils.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* --------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All Rights Reserved.
3+
* See 'LICENSE' in the project root for license information.
4+
* ------------------------------------------------------------------------------------------ */
5+
6+
export enum ArchType {
7+
ia32,
8+
x64
9+
}
10+
11+
export class ArchitectureReplacer {
12+
public static checkAndReplaceWSLPipeProgram(pipeProgramStr: string, expectedArch: ArchType): string {
13+
let replacedPipeProgram: string = null;
14+
const winDir: string = process.env.WINDIR ? process.env.WINDIR.toLowerCase() : null;
15+
const winDirAltDirSep: string = process.env.WINDIR ? process.env.WINDIR.replace('\\', '/').toLowerCase() : null;
16+
const winDirEnv: string = "${env:windir}";
17+
18+
if (winDir && winDirAltDirSep && (pipeProgramStr.indexOf(winDir) === 0 || pipeProgramStr.indexOf(winDirAltDirSep) === 0 || pipeProgramStr.indexOf(winDirEnv) === 0)) {
19+
if (expectedArch === ArchType.x64) {
20+
const pathSep: string = ArchitectureReplacer.checkForFolderInPath(pipeProgramStr, "sysnative");
21+
if (pathSep) {
22+
// User has sysnative but we expect 64 bit. Should be using System32 since sysnative is a 32bit concept.
23+
replacedPipeProgram = pipeProgramStr.replace(`${pathSep}sysnative${pathSep}`, `${pathSep}system32${pathSep}`);
24+
}
25+
} else if (expectedArch === ArchType.ia32) {
26+
const pathSep: string = ArchitectureReplacer.checkForFolderInPath(pipeProgramStr, "system32");
27+
if (pathSep) {
28+
// User has System32 but we expect 32 bit. Should be using sysnative
29+
replacedPipeProgram = pipeProgramStr.replace(`${pathSep}system32${pathSep}`, `${pathSep}sysnative${pathSep}`);
30+
}
31+
}
32+
}
33+
34+
return replacedPipeProgram;
35+
}
36+
37+
// Checks to see if the folder name is in the path using both win and unix style path seperators.
38+
// Returns the path seperator it detected if the folder is in the path.
39+
// Or else it returns empty string to indicate it did not find it in the path.
40+
public static checkForFolderInPath(path: string, folder: string): string {
41+
if (path.indexOf(`/${folder}/`) >= 0) {
42+
return '/';
43+
} else if (path.indexOf(`\\${folder}\\`) >= 0) {
44+
return '\\';
45+
}
46+
47+
return "";
48+
}
49+
}

0 commit comments

Comments
 (0)