Skip to content

Commit

Permalink
fix: correctly parse ps output on linux (#1389)
Browse files Browse the repository at this point in the history
  • Loading branch information
owl-from-hogvarts authored Sep 26, 2023
1 parent 415ae57 commit ac2cfac
Showing 1 changed file with 35 additions and 28 deletions.
63 changes: 35 additions & 28 deletions src/processTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* Copied from https://github.com/microsoft/vscode-node-debug/blob/master/src/node/extension/processTree.ts
*--------------------------------------------------------------------------------------------*/
/* tslint:disable */
'use strict';
'use strict';

import { spawn, ChildProcess } from 'child_process';
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,28 +125,31 @@ 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);
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 => {

// 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)

let command = shortName;
let args = fullCommand;

const pos = fullCommand.indexOf(shortName);
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);
// binaries with spaces in path may not work
// possible solution to read directly from /proc
const commandEndPositionMaybe = fullCommand.indexOf(" ", pos + shortName.length);
const commandEndPosition = commandEndPositionMaybe < 0 ? fullCommand.length : commandEndPositionMaybe;
command = fullCommand.substring(0, commandEndPosition)
args = fullCommand.substring(commandEndPosition).trimStart()
}


if (!isNaN(pid) && !isNaN(ppid)) {
one(pid, ppid, command, args);
}
Expand All @@ -157,8 +160,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 => {
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 +195,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)
}

0 comments on commit ac2cfac

Please sign in to comment.