Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: correctly parse ps output on linux #1389

Merged
merged 6 commits into from
Sep 26, 2023
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 33 additions & 31 deletions src/processTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
*
* Copied from https://github.com/microsoft/vscode-node-debug/blob/master/src/node/extension/processTree.ts
*--------------------------------------------------------------------------------------------*/
/* tslint:disable */
testforstephen marked this conversation as resolved.
Show resolved Hide resolved
'use strict';

import { spawn, ChildProcess } from 'child_process';
'use strict';

import { spawn, ChildProcessWithoutNullStreams } from 'child_process';
import { join } from 'path';

export class ProcessTreeNode {
Expand Down Expand Up @@ -68,7 +68,7 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a

return new Promise((resolve, reject) => {

let proc: ChildProcess;
let proc: ChildProcessWithoutNullStreams;

if (process.platform === 'win32') {

Expand All @@ -77,8 +77,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a

const wmic = join(process.env['WINDIR'] || 'C:\\Windows', 'System32', 'wbem', 'WMIC.exe');
proc = spawn(wmic, [ 'process', 'get', 'CommandLine,CreationDate,ParentProcessId,ProcessId' ]);
proc.stdout?.setEncoding('utf8');
proc.stdout?.on('data', lines(line => {
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', lines(line => {
let matches = CMD_PAT.exec(line.trim());
if (matches && matches.length === 5) {
const pid = Number(matches[4]);
Expand Down Expand Up @@ -110,8 +110,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
} else if (process.platform === 'darwin') { // OS X

proc = spawn('/bin/ps', [ '-x', '-o', `pid,ppid,comm=${'a'.repeat(256)},command` ]);
proc.stdout?.setEncoding('utf8');
proc.stdout?.on('data', lines(line => {
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', lines(line => {

const pid = Number(line.substr(0, 5));
const ppid = Number(line.substr(6, 5));
Expand All @@ -125,27 +125,25 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a

} else { // linux

proc = spawn('/bin/ps', [ '-ax', '-o', 'pid,ppid,comm:20,command' ]);
proc.stdout?.setEncoding('utf8');
proc.stdout?.on('data', lines(line => {

const pid = Number(line.substr(0, 5));
const ppid = Number(line.substr(6, 5));
let command = line.substr(12, 20).trim();
let args = line.substr(33);

let pos = args.indexOf(command);
if (pos >= 0) {
pos = pos + command.length;
while (pos < args.length) {
if (args[pos] === ' ') {
break;
}
pos++;
}
command = args.substr(0, pos);
args = args.substr(pos + 1);
}
proc = spawn('/bin/ps', [ '-ax', '-o', 'pid:6,ppid:6,comm:20,command' ]); // we specify the column width explicitly
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', lines(line => {
testforstephen marked this conversation as resolved.
Show resolved Hide resolved

// the following substr arguments must match the column width specified for the "ps" command above
// regular substr is deprecated
const pid = Number(substr(line, 0, 6));
const ppid = Number(substr(line, 7, 6));
const shortName = substr(line, 14, 20).trim()
const fullCommand = substr(line, 35)

// binaries with spaces in path may not work
// possible solution to read directly from /proc
let pos = fullCommand.indexOf(shortName);
const commandEndPositionMaybe = fullCommand.indexOf(" ", pos + shortName.length)
const commandEndPosition = commandEndPositionMaybe < 0 ? fullCommand.length : commandEndPositionMaybe;

const command = fullCommand.substring(0, commandEndPosition)
const args = fullCommand.substring(commandEndPosition).trimStart()
testforstephen marked this conversation as resolved.
Show resolved Hide resolved

if (!isNaN(pid) && !isNaN(ppid)) {
one(pid, ppid, command, args);
Expand All @@ -157,8 +155,8 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
reject(err);
});

proc.stderr?.setEncoding('utf8');
proc.stderr?.on('data', data => {
proc.stderr.setEncoding('utf8');
proc.stderr.on('data', data => {
testforstephen marked this conversation as resolved.
Show resolved Hide resolved
const e = data.toString();
if (e.indexOf('screen size is bogus') >= 0) {
// ignore this error silently; see https://github.com/microsoft/vscode/issues/75932
Expand Down Expand Up @@ -192,3 +190,7 @@ export function getProcesses(one: (pid: number, ppid: number, command: string, a
});
});
}

function substr(str: string, startIndex: number, length?: number) {
return str.slice(startIndex, length != undefined ? startIndex + length : str.length)
}