Skip to content

Commit 8792252

Browse files
authored
Merge branch 'master' into use-vscode-test
2 parents 73fcf95 + 5497895 commit 8792252

File tree

9 files changed

+108
-42
lines changed

9 files changed

+108
-42
lines changed

debugger.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ The C# debugger supports attaching to processes. To do this, switch to the Debug
7777

7878
![Debug launch configuration drop down](https://raw.githubusercontent.com/wiki/OmniSharp/omnisharp-vscode/images/debug-launch-configurations.png)
7979

80-
Select the '.NET Core Attach' configuration. Clicking the play button (or pressing <kbd>F5</kbd>) will then try to attach. In launch.json, if `processId` is set to `"${command:pickProcess}"` this will provide UI to select which process to attach to.
80+
Select the '.NET Core Attach' configuration. Clicking the play button (or pressing <kbd>F5</kbd>) will then try to attach. In launch.json, if `processId` is set to `""` this will provide UI to select which process to attach to.
8181

8282
#### Remote Debugging
8383

package.json

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,12 +1616,12 @@
16161616
"anyOf": [
16171617
{
16181618
"type": "string",
1619-
"description": "The process id to attach to. Use \"${command:pickProcess}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
1620-
"default": "${command:pickProcess}"
1619+
"description": "The process id to attach to. Use \"\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
1620+
"default": ""
16211621
},
16221622
{
16231623
"type": "integer",
1624-
"description": "The process id to attach to. Use \"${command:pickProcess}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
1624+
"description": "The process id to attach to. Use \"\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
16251625
"default": 0
16261626
}
16271627
]
@@ -2053,8 +2053,7 @@
20532053
"body": {
20542054
"name": ".NET Core Attach",
20552055
"type": "coreclr",
2056-
"request": "attach",
2057-
"processId": "^\"\\${command:pickProcess}\""
2056+
"request": "attach"
20582057
}
20592058
},
20602059
{
@@ -2109,7 +2108,6 @@
21092108
"name": ".NET Core Attach",
21102109
"type": "coreclr",
21112110
"request": "attach",
2112-
"processId": "^\"\\${command:pickRemoteProcess}\"",
21132111
"pipeTransport": {
21142112
"pipeCwd": "^\"\\${workspaceFolder}\"",
21152113
"pipeProgram": "^\"${1:enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'}\"",
@@ -2717,12 +2715,12 @@
27172715
"anyOf": [
27182716
{
27192717
"type": "string",
2720-
"description": "The process id to attach to. Use \"${command:pickProcess}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
2721-
"default": "${command:pickProcess}"
2718+
"description": "The process id to attach to. Use \"\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
2719+
"default": ""
27222720
},
27232721
{
27242722
"type": "integer",
2725-
"description": "The process id to attach to. Use \"${command:pickProcess}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
2723+
"description": "The process id to attach to. Use \"\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
27262724
"default": 0
27272725
}
27282726
]

scripts/remoteProcessPickerScript

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
uname && if [ "$(uname)" = "Linux" ] ; then ps -axww -o pid=,comm=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,args= ; exit; elif [ "$(uname)" = "Darwin" ] ; then ps -axww -o pid=,comm=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,args= -c; fi
1+
uname && if [ "$(uname)" = "Linux" ] ; then ps -axww -o pid=,flags=,comm=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,args= ; exit; elif [ "$(uname)" = "Darwin" ] ; then ps -axww -o pid=,flags=,comm=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,args= -c; fi

src/assets.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,7 @@ export function createAttachConfiguration(): string {
420420
const configuration = {
421421
"name": ".NET Core Attach",
422422
"type": "coreclr",
423-
"request": "attach",
424-
"processId": "\${command:pickProcess}"
423+
"request": "attach"
425424
};
426425

427426
return JSON.stringify(configuration);

src/coreclr-debug/activate.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { EventStream } from '../EventStream';
1313
import CSharpExtensionExports from '../CSharpExtensionExports';
1414
import { getRuntimeDependencyPackageWithId } from '../tools/RuntimeDependencyPackageUtils';
1515
import { getDotnetInfo, DotnetInfo } from '../utils/getDotnetInfo';
16+
import { DotnetDebugConfigurationProvider } from './debugConfigurationProvider';
1617

1718
let _debugUtil: CoreClrDebugUtil = null;
1819

@@ -30,6 +31,8 @@ export async function activate(thisExtension: vscode.Extension<CSharpExtensionEx
3031
}
3132

3233
const factory = new DebugAdapterExecutableFactory(platformInformation, eventStream, thisExtension.packageJSON, thisExtension.extensionPath);
34+
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('coreclr', new DotnetDebugConfigurationProvider(platformInformation)));
35+
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('clr', new DotnetDebugConfigurationProvider(platformInformation)));
3336
context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('coreclr', factory));
3437
context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('clr', factory));
3538
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
8+
import { RemoteAttachPicker, DotNetAttachItemsProviderFactory, AttachPicker, AttachItem } from '../features/processPicker';
9+
import { PlatformInformation } from '../platform';
10+
11+
export class DotnetDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
12+
constructor(public platformInformation: PlatformInformation) {}
13+
14+
public async resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, debugConfiguration: vscode.DebugConfiguration, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration>
15+
{
16+
if (!debugConfiguration)
17+
{
18+
return null;
19+
}
20+
21+
// Process Id is empty, handle Attach to Process Dialog.
22+
if (debugConfiguration.request === "attach" && !debugConfiguration.processId && !debugConfiguration.processName)
23+
{
24+
let process: AttachItem = undefined;
25+
if (debugConfiguration.pipeTransport)
26+
{
27+
process = await RemoteAttachPicker.ShowAttachEntries(debugConfiguration, this.platformInformation);
28+
}
29+
else
30+
{
31+
let attachItemsProvider = DotNetAttachItemsProviderFactory.Get();
32+
let attacher = new AttachPicker(attachItemsProvider);
33+
process = await attacher.ShowAttachEntries();
34+
}
35+
36+
if (process)
37+
{
38+
debugConfiguration.processId = process.id;
39+
40+
if (debugConfiguration.type == "coreclr" &&
41+
this.platformInformation.isMacOS() &&
42+
this.platformInformation.architecture == 'arm64')
43+
{
44+
// For Apple Silicon M1, it is possible that the process we are attaching to is being emulated as x86_64.
45+
// The process is emulated if it has process flags has P_TRANSLATED (0x20000).
46+
if (process.flags & 0x20000)
47+
{
48+
debugConfiguration.targetArchitecture = "x86_64";
49+
}
50+
else
51+
{
52+
debugConfiguration.targetArchitecture = "arm64";
53+
}
54+
}
55+
}
56+
else
57+
{
58+
throw new Error("No process was selected.");
59+
}
60+
}
61+
62+
return debugConfiguration;
63+
}
64+
}

src/features/commands.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import * as fs from 'fs';
1111
import * as path from 'path';
1212
import * as protocol from '../omnisharp/protocol';
1313
import * as vscode from 'vscode';
14-
import { DotNetAttachItemsProviderFactory, AttachPicker, RemoteAttachPicker } from './processPicker';
1514
import { generateAssets } from '../assets';
1615
import { ShowOmniSharpChannel, CommandDotNetRestoreStart, CommandDotNetRestoreProgress, CommandDotNetRestoreSucceeded, CommandDotNetRestoreFailed } from '../omnisharp/loggingEvents';
1716
import { EventStream } from '../EventStream';
@@ -40,14 +39,13 @@ export default function registerCommands(context: vscode.ExtensionContext, serve
4039
// running the command activates the extension, which is all we need for installation to kickoff
4140
disposable.add(vscode.commands.registerCommand('csharp.downloadDebugger', () => { }));
4241

43-
// register process picker for attach
44-
let attachItemsProvider = DotNetAttachItemsProviderFactory.Get();
45-
let attacher = new AttachPicker(attachItemsProvider);
46-
disposable.add(vscode.commands.registerCommand('csharp.listProcess', async () => attacher.ShowAttachEntries()));
42+
// register process picker for attach for legacy configurations.
43+
disposable.add(vscode.commands.registerCommand('csharp.listProcess', () => ""));
44+
disposable.add(vscode.commands.registerCommand('csharp.listRemoteProcess', () => ""));
45+
46+
4747
// Register command for generating tasks.json and launch.json assets.
4848
disposable.add(vscode.commands.registerCommand('dotnet.generateAssets', async (selectedIndex) => generateAssets(server, selectedIndex)));
49-
// Register command for remote process picker for attach
50-
disposable.add(vscode.commands.registerCommand('csharp.listRemoteProcess', async (args) => RemoteAttachPicker.ShowAttachEntries(args, platformInfo)));
5149

5250
disposable.add(vscode.commands.registerCommand('csharp.reportIssue', async () => reportIssue(vscode, eventStream, getDotnetInfo, platformInfo.isValidPlatformForMono(), optionProvider.GetLatestOptions(), monoResolver)));
5351

src/features/processPicker.ts

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { getExtensionPath } from '../common';
1414

1515
export interface AttachItem extends vscode.QuickPickItem {
1616
id: string;
17+
flags: number;
1718
}
1819

1920
export interface AttachItemsProvider {
@@ -23,7 +24,7 @@ export interface AttachItemsProvider {
2324
export class AttachPicker {
2425
constructor(private attachItemsProvider: AttachItemsProvider) { }
2526

26-
public async ShowAttachEntries(): Promise<string> {
27+
public async ShowAttachEntries(): Promise<AttachItem> {
2728
return this.attachItemsProvider.getAttachItems()
2829
.then(processEntries => {
2930
let attachPickOptions: vscode.QuickPickOptions = {
@@ -35,7 +36,7 @@ export class AttachPicker {
3536

3637
return vscode.window.showQuickPick(processEntries, attachPickOptions)
3738
.then(chosenProcess => {
38-
return chosenProcess ? chosenProcess.id : null;
39+
return chosenProcess;
3940
});
4041
});
4142
}
@@ -50,8 +51,8 @@ interface IPipeTransportOptions {
5051

5152
export class RemoteAttachPicker {
5253
public static get commColumnTitle() { return Array(PsOutputParser.secondColumnCharacters).join("a"); }
53-
public static get linuxPsCommand() { return `ps axww -o pid=,comm=${RemoteAttachPicker.commColumnTitle},args=`; }
54-
public static get osxPsCommand() { return `ps axww -o pid=,comm=${RemoteAttachPicker.commColumnTitle},args= -c`; }
54+
public static get linuxPsCommand() { return `ps axww -o pid=,flags=,comm=${RemoteAttachPicker.commColumnTitle},args=`; }
55+
public static get osxPsCommand() { return `ps axww -o pid=,flags=,comm=${RemoteAttachPicker.commColumnTitle},args= -c`; }
5556
public static get debuggerCommand() { return "${debuggerCommand}"; }
5657
public static get scriptShellCmd() { return "sh -s"; }
5758

@@ -196,7 +197,7 @@ export class RemoteAttachPicker {
196197
return args.map(arg => this.quoteArg(arg)).join(" ");
197198
}
198199

199-
public static async ShowAttachEntries(args: any, platformInfo: PlatformInformation): Promise<string> {
200+
public static async ShowAttachEntries(args: any, platformInfo: PlatformInformation): Promise<AttachItem> {
200201
// Create remote attach output channel for errors.
201202
if (!RemoteAttachPicker._channel) {
202203
RemoteAttachPicker._channel = vscode.window.createOutputChannel('remote-attach');
@@ -210,13 +211,13 @@ export class RemoteAttachPicker {
210211

211212
if (!name) {
212213
// Config name not found.
213-
return Promise.reject<string>(new Error("Name not defined in current configuration."));
214+
return Promise.reject<AttachItem>(new Error("Name not defined in current configuration."));
214215
}
215216

216217
if (!args.pipeTransport || !args.pipeTransport.debuggerPath) {
217218
// Missing PipeTransport and debuggerPath, prompt if user wanted to just do local attach.
218-
return Promise.reject<string>(new Error("Configuration \"" + name + "\" in launch.json does not have a " +
219-
"pipeTransport argument with debuggerPath for pickRemoteProcess. Use pickProcess for local attach."));
219+
return Promise.reject<AttachItem>(new Error("Configuration \"" + name + "\" in launch.json does not have a " +
220+
"pipeTransport argument with debuggerPath for remote process listing."));
220221
} else {
221222
let pipeTransport = this.getPipeTransportOptions(args.pipeTransport, os.platform());
222223

@@ -230,8 +231,7 @@ export class RemoteAttachPicker {
230231
placeHolder: "Select the process to attach to"
231232
};
232233
return vscode.window.showQuickPick(processes, attachPickOptions);
233-
})
234-
.then(item => { return item ? item.id : Promise.reject<string>(new Error("Could not find a process id to attach.")); });
234+
});
235235
}
236236
}
237237

@@ -266,14 +266,15 @@ export class RemoteAttachPicker {
266266
}
267267

268268
class Process {
269-
constructor(public name: string, public pid: string, public commandLine: string) { }
269+
constructor(public name: string, public pid: string, public commandLine: string, public flags: number) { }
270270

271271
public toAttachItem(): AttachItem {
272272
return {
273273
label: this.name,
274274
description: this.pid,
275275
detail: this.commandLine,
276-
id: this.pid
276+
id: this.pid,
277+
flags: this.flags
277278
};
278279
}
279280
}
@@ -404,17 +405,20 @@ export class PsOutputParser {
404405
// - any leading whitespace
405406
// - PID
406407
// - whitespace
408+
// - flags (hex value)
409+
// - whitespace
407410
// - executable name --> this is PsAttachItemsProvider.secondColumnCharacters - 1 because ps reserves one character
408411
// for the whitespace separator
409412
// - whitespace
410413
// - args (might be empty)
411-
const psEntry = new RegExp(`^\\s*([0-9]+)\\s+(.{${PsOutputParser.secondColumnCharacters - 1}})\\s+(.*)$`);
414+
const psEntry = new RegExp(`^\\s*([0-9]+)\\s+([0-9a-fA-F]+)\\s+(.{${PsOutputParser.secondColumnCharacters - 1}})\\s+(.*)$`);
412415
const matches = psEntry.exec(line);
413-
if (matches && matches.length === 4) {
416+
if (matches && matches.length === 5) {
414417
const pid = matches[1].trim();
415-
const executable = matches[2].trim();
416-
const cmdline = matches[3].trim();
417-
return new Process(executable, pid, cmdline);
418+
const flags = parseInt(matches[2].trim(), 16); // flags comes in as hex
419+
const executable = matches[3].trim();
420+
const cmdline = matches[4].trim();
421+
return new Process(executable, pid, cmdline, flags);
418422
}
419423
}
420424
}
@@ -444,7 +448,7 @@ export class WmicOutputParser {
444448
// Only public for tests.
445449
public static parseProcessFromWmic(processes: string): Process[] {
446450
let lines = processes.split(os.EOL);
447-
let currentProcess: Process = new Process(null, null, null);
451+
let currentProcess: Process = new Process(null, null, null, null);
448452
let processEntries: Process[] = [];
449453

450454
for (let i = 0; i < lines.length; i++) {
@@ -458,7 +462,7 @@ export class WmicOutputParser {
458462
// Each entry of processes has ProcessId as the last line
459463
if (line.startsWith(WmicOutputParser.wmicPidTitle)) {
460464
processEntries.push(currentProcess);
461-
currentProcess = new Process(null, null, null);
465+
currentProcess = new Process(null, null, null, null);
462466
}
463467
}
464468

src/tools/OptionsSchema.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,12 @@
406406
"anyOf": [
407407
{
408408
"type": "string",
409-
"description": "The process id to attach to. Use \"${command:pickProcess}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
410-
"default": "${command:pickProcess}"
409+
"description": "The process id to attach to. Use \"\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
410+
"default": ""
411411
},
412412
{
413413
"type": "integer",
414-
"description": "The process id to attach to. Use \"${command:pickProcess}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
414+
"description": "The process id to attach to. Use \"\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.",
415415
"default": 0
416416
}
417417
]

0 commit comments

Comments
 (0)