Add processFilter for remote attach process selection - #14684
Conversation
|
@microsoft-github-policy-service agree company="Siemens AG"
|
There was a problem hiding this comment.
Pull request overview
Adds regex-based remote process selection for cppdbg attach configurations.
Changes:
- Filters remote process candidates by label, description, or detail.
- Automatically attaches on one match and narrows the picker on multiple matches.
- Adds configuration schema, documentation, and unit tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
Extension/src/Debugger/processFilter.ts |
Implements process filtering and regex validation. |
Extension/src/Debugger/attachToProcess.ts |
Applies filtering during remote attach. |
Extension/test/unit/processFilter.test.ts |
Tests matching and validation behavior. |
Extension/package.json |
Defines the processFilter configuration property. |
Extension/package.nls.json |
Documents the new property. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The old ATTACH mode started gdbserver with "--attach :<port> $(pidof <binary>)" and used a plain "request": "launch" config. This is the classic cpptools attach setup, which is fragile and has several long-standing, unfixed bugs, e.g. microsoft/vscode-cpptools#4166. { "name": "Attach with GDB", "type": "cppdbg", "request": "launch", "program": "<program>", "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "postDebugTask": "kill_gdbserver_..." } cppdbg also supports attaching over the extended-remote protocol: { "name": "Attach with GDB", "type": "cppdbg", "request": "attach", "program": "<program>", "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "useExtendedRemote": true } Switch to this instead: merge ATTACH into the same persistent "gdbserver --multi" server already used for MULTI mode, since both are now extended-remote sessions that only differ on the client side, and stop it by PID instead of pgrep/killall. ONCE mode gets the same readiness synchronization MULTI already had, since gdbserver now always writes a PID file that the stop commands wait on. Allocate a separate debug server port for each mode. This prevents the persistent attach endpoint from colliding with a once session for the same binary. Until microsoft/vscode-cpptools#14684 is merged, this comes with one downside (which was the blocker for using extended-remote attach mode until now): the user is prompted to pick the process to attach to, instead of it being selected automatically. But this is a temporary limitation, and the new setup is more robust and fixes several long-standing issues with the old ATTACH mode. Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
The old ATTACH mode started gdbserver with "--attach :<port> $(pidof <binary>)" and used a plain "request": "launch" config. This is the classic cpptools attach setup, which is fragile and has several long-standing, unfixed bugs, e.g. microsoft/vscode-cpptools#4166. { "name": "Attach with GDB", "type": "cppdbg", "request": "launch", "program": "<program>", "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "postDebugTask": "kill_gdbserver_..." } cppdbg also supports attaching over the extended-remote protocol: { "name": "Attach with GDB", "type": "cppdbg", "request": "attach", "program": "<program>", "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "useExtendedRemote": true } Switch to this instead: merge ATTACH into the same persistent "gdbserver --multi" server already used for MULTI mode, since both are now extended-remote sessions that only differ on the client side, and stop it by PID instead of pgrep/killall. ONCE mode gets the same readiness synchronization MULTI already had, since gdbserver now always writes a PID file that the stop commands wait on. Allocate a separate debug server port for each mode. This prevents the persistent attach endpoint from colliding with a once session for the same binary. Until microsoft/vscode-cpptools#14684 is merged, this comes with one downside (which was the blocker for using extended-remote attach mode until now): the user is prompted to pick the process to attach to, instead of it being selected automatically. But this is a temporary limitation, and the new setup is more robust and fixes several long-standing issues with the old ATTACH mode. Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
The old ATTACH mode started gdbserver with "--attach :<port> $(pidof <binary>)" and used a plain "request": "launch" config. This is the classic cpptools attach setup, which is fragile and has several long-standing, unfixed bugs, e.g. microsoft/vscode-cpptools#4166. { "name": "Attach with GDB", "type": "cppdbg", "request": "launch", "program": "<program>", "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "postDebugTask": "kill_gdbserver_..." } cppdbg also supports attaching over the extended-remote protocol: { "name": "Attach with GDB", "type": "cppdbg", "request": "attach", "program": "<program>", "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "useExtendedRemote": true } Switch to this instead: merge ATTACH into the same persistent "gdbserver --multi" server already used for MULTI mode, since both are now extended-remote sessions that only differ on the client side, and stop it by PID instead of pgrep/killall. ONCE mode gets the same readiness synchronization MULTI already had, since gdbserver now always writes a PID file that the stop commands wait on. Allocate a separate debug server port for each mode. This prevents the persistent attach endpoint from colliding with a once session for the same binary. Until microsoft/vscode-cpptools#14684 is merged, this comes with one downside (which was the blocker for using extended-remote attach mode until now): the user is prompted to pick the process to attach to, instead of it being selected automatically. But this is a temporary limitation, and the new setup is more robust and fixes several long-standing issues with the old ATTACH mode. Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
The old ATTACH mode started gdbserver with "--attach :<port> $(pidof <binary>)" and used a plain "request": "launch" config. This is the classic cpptools attach setup, which is fragile and has several long-standing, unfixed bugs, e.g. microsoft/vscode-cpptools#4166. { "name": "Attach with GDB", "type": "cppdbg", "request": "launch", "program": "<program>", "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "postDebugTask": "kill_gdbserver_..." } cppdbg also supports attaching over the extended-remote protocol: { "name": "Attach with GDB", "type": "cppdbg", "request": "attach", "program": "<program>", "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "useExtendedRemote": true } Switch to this instead: merge ATTACH into the same persistent "gdbserver --multi" server already used for MULTI mode, since both are now extended-remote sessions that only differ on the client side, and stop it by PID instead of pgrep/killall. ONCE mode gets the same readiness synchronization MULTI already had, since gdbserver now always writes a PID file that the stop commands wait on. Allocate a separate debug server port for each mode. This prevents the persistent attach endpoint from colliding with a once session for the same binary. Until microsoft/vscode-cpptools#14684 is merged, this comes with one downside (which was the blocker for using extended-remote attach mode until now): the user is prompted to pick the process to attach to, instead of it being selected automatically. But this is a temporary limitation, and the new setup is more robust and fixes several long-standing issues with the old ATTACH mode. Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
The old ATTACH mode started gdbserver with "--attach :<port> $(pidof <binary>)" and used a plain "request": "launch" config. This is the classic cpptools attach setup, which is fragile and has several long-standing, unfixed bugs, e.g. microsoft/vscode-cpptools#4166. { "name": "Attach with GDB", "type": "cppdbg", "request": "launch", "program": "<program>", "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "postDebugTask": "kill_gdbserver_..." } cppdbg also supports attaching over the extended-remote protocol: { "name": "Attach with GDB", "type": "cppdbg", "request": "attach", "program": "<program>", "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "useExtendedRemote": true } Switch to this instead: merge ATTACH into the same persistent "gdbserver --multi" server already used for MULTI mode, since both are now extended-remote sessions that only differ on the client side, and stop it by PID instead of pgrep/killall. ONCE mode gets the same readiness synchronization MULTI already had, since gdbserver now always writes a PID file that the stop commands wait on. Allocate a separate debug server port for each mode. This prevents the persistent attach endpoint from colliding with a once session for the same binary. Until microsoft/vscode-cpptools#14684 is merged, this comes with one downside (which was the blocker for using extended-remote attach mode until now): the user is prompted to pick the process to attach to, instead of it being selected automatically. But this is a temporary limitation, and the new setup is more robust and fixes several long-standing issues with the old ATTACH mode. Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
The old ATTACH mode started gdbserver with "--attach :<port> $(pidof <binary>)" and used a plain "request": "launch" config. This is the classic cpptools attach setup, which is fragile and has several long-standing, unfixed bugs, e.g. microsoft/vscode-cpptools#4166. { "name": "Attach with GDB", "type": "cppdbg", "request": "launch", "program": "<program>", "stopAtEntry": true, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "postDebugTask": "kill_gdbserver_..." } cppdbg also supports attaching over the extended-remote protocol: { "name": "Attach with GDB", "type": "cppdbg", "request": "attach", "program": "<program>", "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "miDebuggerServerAddress": "<target>:<port>", "useExtendedRemote": true } Switch to this instead: merge ATTACH into the same persistent "gdbserver --multi" server already used for MULTI mode, since both are now extended-remote sessions that only differ on the client side, and stop it by PID instead of pgrep/killall. ONCE mode gets the same readiness synchronization MULTI already had, since gdbserver now always writes a PID file that the stop commands wait on. Allocate a separate debug server port for each mode. This prevents the persistent attach endpoint from colliding with a once session for the same binary. Until microsoft/vscode-cpptools#14684 is merged, this comes with one downside (which was the blocker for using extended-remote attach mode until now): the user is prompted to pick the process to attach to, instead of it being selected automatically. But this is a temporary limitation, and the new setup is more robust and fixes several long-standing issues with the old ATTACH mode. Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
16a545f to
171cb46
Compare
Sean McManus (sean-mcmanus)
left a comment
There was a problem hiding this comment.
✨Copilot (agent135): [Moderate] Two correctness findings and one localization finding are noted inline.
b99b948 to
98331ee
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Missing process fields are treated as empty strings, allowing some filters to select processes they do not actually match.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 2
- Review effort level: Balanced
When attaching to a process on a remote target, the process always has to be selected by hand, even though the launch configuration already knows which executable it belongs to. A generated configuration cannot hard-code processId either, because the pid changes on every boot and on every restart of the service, so the picker is the only option. Add an optional processFilter regular expression to the cppdbg attach configuration. When set, it is matched against the label, description and detail of the remote process list: exactly one match attach to that process directly more than one show the picker with only the matching entries no match show the full picker, as before All three fields are considered because the item format depends on the transport: useExtendedRemote reports the user and the full command line in the label, while pipeTransport reports the process name in the label and the command line in the detail. An invalid regular expression is reported instead of being silently ignored. This affects remote attach only (pipeTransport and useExtendedRemote); local attach continues to use program-based matching. Closes microsoft#14682
Move the matching logic out of RemoteAttachPicker into a standalone function so that it can be unit tested without a VS Code quick pick or a live connection to a remote target. No functional change.
Cover empty and non-string filter values, matching against label, description and detail, multiple matches, and an invalid regular expression.
3c69b26 to
a98898d
Compare
Sean McManus (sean-mcmanus)
left a comment
There was a problem hiding this comment.
✨Copilot (agent135): [Minor] The two Copilot findings are fixed; one focused regression-test gap remains inline.
| deepStrictEqual(filterProcessItems(processes, 'worker')?.map(p => p.id), ['102']); | ||
| }); | ||
|
|
||
| it('preserves edge whitespace in the regular expression', () => { |
There was a problem hiding this comment.
✨Copilot (agent135): [Minor] Please add a regression case for the absent-field behavior fixed in this revision. With this fixture, filterProcessItems(processes, '^$') should return no entries because the missing detail fields are not empty strings; an explicitly empty field can be included to preserve that distinction. This test would fail the prior ?? "" implementation and directly protect the fix.
Problem
When attaching to a process on a remote target (
useExtendedRemoteorpipeTransport), the process to attach to always has to be picked manually from the full process list on every debug session, even though a generatedlaunch.jsonalready knows which executable it targets. The PID can't be hard-coded because it changes on every restart/boot, and picking the wrong entry silently produces a session with mismatched symbols and source mappings.This mirrors the existing
program-based auto-selection already used for local attach (findProcessByProgramName), which does not apply to remote attach because the remote process list comes from a different source (RemoteAttachPicker) and itslabel/detailshapes differ per transport.Solution
Adds an optional
processFilter(regular expression) to thecppdbgattach configuration:label,description, anddetailof each remote process entry (the exact fields differ by transport:useExtendedRemoteputs the user + full command line inlabel;pipeTransportputs the process name inlabeland the command line indetail).Scope: this only affects remote attach (
pipeTransport/useExtendedRemote). Local attach is unaffected by this PR.Example
launch.json:{ "name": "attach my-daemon", "type": "cppdbg", "request": "attach", "program": "/path/on/build/host/to/unstripped/my-daemon", "MIMode": "gdb", "miDebuggerPath": "/path/to/aarch64-poky-linux-gdb", "miDebuggerServerAddress": "192.168.7.2:1234", "useExtendedRemote": true, "processFilter": "/usr/bin/my-daemon" }Closes #14682.
Open question for maintainers
Should
processFilteralso apply to local attach, in addition to (or instead of) the existingprogram-based basename matching? Sinceprogramis a required field forcppdbgattach, both would typically be present locally at the same time, so the semantics need a decision — I'd lean towards intersecting with theprogrammatch (never lettingprocessFilteralone select a process unrelated toprogram) rather than giving it precedence, but wanted to keep this PR scoped to the originally requested remote-only case and get feedback before extending it.Testing
Extension/test/unit/processFilter.test.ts.gdbserver --multitarget withuseExtendedRemote: true:processFiltermatch attaches directly without showing the picker