diff --git a/debugger.md b/debugger.md
index f1ca107c3..bfaa1b0d6 100644
--- a/debugger.md
+++ b/debugger.md
@@ -77,7 +77,7 @@ The C# debugger supports attaching to processes. To do this, switch to the Debug
![Debug launch configuration drop down](https://raw.githubusercontent.com/wiki/OmniSharp/omnisharp-vscode/images/debug-launch-configurations.png)
-Select the '.NET Core Attach' configuration. Clicking the play button (or pressing F5) 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.
+Select the '.NET Core Attach' configuration. Clicking the play button (or pressing F5) will then try to attach. In launch.json, if `processId` is set to `""` this will provide UI to select which process to attach to.
#### Remote Debugging
diff --git a/package.json b/package.json
index 5f1fdd9c4..0fbbace4b 100644
--- a/package.json
+++ b/package.json
@@ -1624,12 +1624,12 @@
"anyOf": [
{
"type": "string",
- "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.",
- "default": "${command:pickProcess}"
+ "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.",
+ "default": ""
},
{
"type": "integer",
- "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.",
+ "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.",
"default": 0
}
]
@@ -2061,8 +2061,7 @@
"body": {
"name": ".NET Core Attach",
"type": "coreclr",
- "request": "attach",
- "processId": "^\"\\${command:pickProcess}\""
+ "request": "attach"
}
},
{
@@ -2117,7 +2116,6 @@
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
- "processId": "^\"\\${command:pickRemoteProcess}\"",
"pipeTransport": {
"pipeCwd": "^\"\\${workspaceFolder}\"",
"pipeProgram": "^\"${1:enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'}\"",
@@ -2725,12 +2723,12 @@
"anyOf": [
{
"type": "string",
- "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.",
- "default": "${command:pickProcess}"
+ "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.",
+ "default": ""
},
{
"type": "integer",
- "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.",
+ "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.",
"default": 0
}
]
diff --git a/scripts/remoteProcessPickerScript b/scripts/remoteProcessPickerScript
index fd2e75a76..4c6e94748 100644
--- a/scripts/remoteProcessPickerScript
+++ b/scripts/remoteProcessPickerScript
@@ -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
+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
\ No newline at end of file
diff --git a/src/assets.ts b/src/assets.ts
index 96a5e9757..5b931aec9 100644
--- a/src/assets.ts
+++ b/src/assets.ts
@@ -420,8 +420,7 @@ export function createAttachConfiguration(): string {
const configuration = {
"name": ".NET Core Attach",
"type": "coreclr",
- "request": "attach",
- "processId": "\${command:pickProcess}"
+ "request": "attach"
};
return JSON.stringify(configuration);
diff --git a/src/coreclr-debug/activate.ts b/src/coreclr-debug/activate.ts
index 8c8ca72d7..e515ac285 100644
--- a/src/coreclr-debug/activate.ts
+++ b/src/coreclr-debug/activate.ts
@@ -13,6 +13,7 @@ import { EventStream } from '../EventStream';
import CSharpExtensionExports from '../CSharpExtensionExports';
import { getRuntimeDependencyPackageWithId } from '../tools/RuntimeDependencyPackageUtils';
import { getDotnetInfo, DotnetInfo } from '../utils/getDotnetInfo';
+import { DotnetDebugConfigurationProvider } from './debugConfigurationProvider';
let _debugUtil: CoreClrDebugUtil = null;
@@ -30,6 +31,8 @@ export async function activate(thisExtension: vscode.Extension
+ {
+ if (!debugConfiguration)
+ {
+ return null;
+ }
+
+ // Process Id is empty, handle Attach to Process Dialog.
+ if (debugConfiguration.request === "attach" && !debugConfiguration.processId && !debugConfiguration.processName)
+ {
+ let process: AttachItem = undefined;
+ if (debugConfiguration.pipeTransport)
+ {
+ process = await RemoteAttachPicker.ShowAttachEntries(debugConfiguration, this.platformInformation);
+ }
+ else
+ {
+ let attachItemsProvider = DotNetAttachItemsProviderFactory.Get();
+ let attacher = new AttachPicker(attachItemsProvider);
+ process = await attacher.ShowAttachEntries();
+ }
+
+ if (process)
+ {
+ debugConfiguration.processId = process.id;
+
+ if (debugConfiguration.type == "coreclr" &&
+ this.platformInformation.isMacOS() &&
+ this.platformInformation.architecture == 'arm64')
+ {
+ // For Apple Silicon M1, it is possible that the process we are attaching to is being emulated as x86_64.
+ // The process is emulated if it has process flags has P_TRANSLATED (0x20000).
+ if (process.flags & 0x20000)
+ {
+ debugConfiguration.targetArchitecture = "x86_64";
+ }
+ else
+ {
+ debugConfiguration.targetArchitecture = "arm64";
+ }
+ }
+ }
+ else
+ {
+ throw new Error("No process was selected.");
+ }
+ }
+
+ return debugConfiguration;
+ }
+}
\ No newline at end of file
diff --git a/src/features/commands.ts b/src/features/commands.ts
index df2312b56..efae7cc47 100644
--- a/src/features/commands.ts
+++ b/src/features/commands.ts
@@ -11,7 +11,6 @@ import * as fs from 'fs';
import * as path from 'path';
import * as protocol from '../omnisharp/protocol';
import * as vscode from 'vscode';
-import { DotNetAttachItemsProviderFactory, AttachPicker, RemoteAttachPicker } from './processPicker';
import { generateAssets } from '../assets';
import { ShowOmniSharpChannel, CommandDotNetRestoreStart, CommandDotNetRestoreProgress, CommandDotNetRestoreSucceeded, CommandDotNetRestoreFailed } from '../omnisharp/loggingEvents';
import { EventStream } from '../EventStream';
@@ -40,14 +39,13 @@ export default function registerCommands(context: vscode.ExtensionContext, serve
// running the command activates the extension, which is all we need for installation to kickoff
disposable.add(vscode.commands.registerCommand('csharp.downloadDebugger', () => { }));
- // register process picker for attach
- let attachItemsProvider = DotNetAttachItemsProviderFactory.Get();
- let attacher = new AttachPicker(attachItemsProvider);
- disposable.add(vscode.commands.registerCommand('csharp.listProcess', async () => attacher.ShowAttachEntries()));
+ // register process picker for attach for legacy configurations.
+ disposable.add(vscode.commands.registerCommand('csharp.listProcess', () => ""));
+ disposable.add(vscode.commands.registerCommand('csharp.listRemoteProcess', () => ""));
+
+
// Register command for generating tasks.json and launch.json assets.
disposable.add(vscode.commands.registerCommand('dotnet.generateAssets', async (selectedIndex) => generateAssets(server, selectedIndex)));
- // Register command for remote process picker for attach
- disposable.add(vscode.commands.registerCommand('csharp.listRemoteProcess', async (args) => RemoteAttachPicker.ShowAttachEntries(args, platformInfo)));
disposable.add(vscode.commands.registerCommand('csharp.reportIssue', async () => reportIssue(vscode, eventStream, getDotnetInfo, platformInfo.isValidPlatformForMono(), optionProvider.GetLatestOptions(), monoResolver)));
diff --git a/src/features/processPicker.ts b/src/features/processPicker.ts
index 2a2294df1..900efe37b 100644
--- a/src/features/processPicker.ts
+++ b/src/features/processPicker.ts
@@ -14,6 +14,7 @@ import { getExtensionPath } from '../common';
export interface AttachItem extends vscode.QuickPickItem {
id: string;
+ flags: number;
}
export interface AttachItemsProvider {
@@ -23,7 +24,7 @@ export interface AttachItemsProvider {
export class AttachPicker {
constructor(private attachItemsProvider: AttachItemsProvider) { }
- public async ShowAttachEntries(): Promise {
+ public async ShowAttachEntries(): Promise {
return this.attachItemsProvider.getAttachItems()
.then(processEntries => {
let attachPickOptions: vscode.QuickPickOptions = {
@@ -35,7 +36,7 @@ export class AttachPicker {
return vscode.window.showQuickPick(processEntries, attachPickOptions)
.then(chosenProcess => {
- return chosenProcess ? chosenProcess.id : null;
+ return chosenProcess;
});
});
}
@@ -50,8 +51,8 @@ interface IPipeTransportOptions {
export class RemoteAttachPicker {
public static get commColumnTitle() { return Array(PsOutputParser.secondColumnCharacters).join("a"); }
- public static get linuxPsCommand() { return `ps axww -o pid=,comm=${RemoteAttachPicker.commColumnTitle},args=`; }
- public static get osxPsCommand() { return `ps axww -o pid=,comm=${RemoteAttachPicker.commColumnTitle},args= -c`; }
+ public static get linuxPsCommand() { return `ps axww -o pid=,flags=,comm=${RemoteAttachPicker.commColumnTitle},args=`; }
+ public static get osxPsCommand() { return `ps axww -o pid=,flags=,comm=${RemoteAttachPicker.commColumnTitle},args= -c`; }
public static get debuggerCommand() { return "${debuggerCommand}"; }
public static get scriptShellCmd() { return "sh -s"; }
@@ -196,7 +197,7 @@ export class RemoteAttachPicker {
return args.map(arg => this.quoteArg(arg)).join(" ");
}
- public static async ShowAttachEntries(args: any, platformInfo: PlatformInformation): Promise {
+ public static async ShowAttachEntries(args: any, platformInfo: PlatformInformation): Promise {
// Create remote attach output channel for errors.
if (!RemoteAttachPicker._channel) {
RemoteAttachPicker._channel = vscode.window.createOutputChannel('remote-attach');
@@ -210,13 +211,13 @@ export class RemoteAttachPicker {
if (!name) {
// Config name not found.
- return Promise.reject(new Error("Name not defined in current configuration."));
+ return Promise.reject(new Error("Name not defined in current configuration."));
}
if (!args.pipeTransport || !args.pipeTransport.debuggerPath) {
// Missing PipeTransport and debuggerPath, prompt if user wanted to just do local attach.
- return Promise.reject(new Error("Configuration \"" + name + "\" in launch.json does not have a " +
- "pipeTransport argument with debuggerPath for pickRemoteProcess. Use pickProcess for local attach."));
+ return Promise.reject(new Error("Configuration \"" + name + "\" in launch.json does not have a " +
+ "pipeTransport argument with debuggerPath for remote process listing."));
} else {
let pipeTransport = this.getPipeTransportOptions(args.pipeTransport, os.platform());
@@ -230,8 +231,7 @@ export class RemoteAttachPicker {
placeHolder: "Select the process to attach to"
};
return vscode.window.showQuickPick(processes, attachPickOptions);
- })
- .then(item => { return item ? item.id : Promise.reject(new Error("Could not find a process id to attach.")); });
+ });
}
}
@@ -266,14 +266,15 @@ export class RemoteAttachPicker {
}
class Process {
- constructor(public name: string, public pid: string, public commandLine: string) { }
+ constructor(public name: string, public pid: string, public commandLine: string, public flags: number) { }
public toAttachItem(): AttachItem {
return {
label: this.name,
description: this.pid,
detail: this.commandLine,
- id: this.pid
+ id: this.pid,
+ flags: this.flags
};
}
}
@@ -404,17 +405,20 @@ export class PsOutputParser {
// - any leading whitespace
// - PID
// - whitespace
+ // - flags (hex value)
+ // - whitespace
// - executable name --> this is PsAttachItemsProvider.secondColumnCharacters - 1 because ps reserves one character
// for the whitespace separator
// - whitespace
// - args (might be empty)
- const psEntry = new RegExp(`^\\s*([0-9]+)\\s+(.{${PsOutputParser.secondColumnCharacters - 1}})\\s+(.*)$`);
+ const psEntry = new RegExp(`^\\s*([0-9]+)\\s+([0-9a-fA-F]+)\\s+(.{${PsOutputParser.secondColumnCharacters - 1}})\\s+(.*)$`);
const matches = psEntry.exec(line);
- if (matches && matches.length === 4) {
+ if (matches && matches.length === 5) {
const pid = matches[1].trim();
- const executable = matches[2].trim();
- const cmdline = matches[3].trim();
- return new Process(executable, pid, cmdline);
+ const flags = parseInt(matches[2].trim(), 16); // flags comes in as hex
+ const executable = matches[3].trim();
+ const cmdline = matches[4].trim();
+ return new Process(executable, pid, cmdline, flags);
}
}
}
@@ -444,7 +448,7 @@ export class WmicOutputParser {
// Only public for tests.
public static parseProcessFromWmic(processes: string): Process[] {
let lines = processes.split(os.EOL);
- let currentProcess: Process = new Process(null, null, null);
+ let currentProcess: Process = new Process(null, null, null, null);
let processEntries: Process[] = [];
for (let i = 0; i < lines.length; i++) {
@@ -458,7 +462,7 @@ export class WmicOutputParser {
// Each entry of processes has ProcessId as the last line
if (line.startsWith(WmicOutputParser.wmicPidTitle)) {
processEntries.push(currentProcess);
- currentProcess = new Process(null, null, null);
+ currentProcess = new Process(null, null, null, null);
}
}
diff --git a/src/tools/OptionsSchema.json b/src/tools/OptionsSchema.json
index f43342d28..8dc938413 100644
--- a/src/tools/OptionsSchema.json
+++ b/src/tools/OptionsSchema.json
@@ -406,12 +406,12 @@
"anyOf": [
{
"type": "string",
- "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.",
- "default": "${command:pickProcess}"
+ "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.",
+ "default": ""
},
{
"type": "integer",
- "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.",
+ "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.",
"default": 0
}
]