
























@@ -1677,15 +1677,20 @@ async function samplePosixProcessWithDescendants(pid, run) {
16771677const { stdout } = await run("ps", POSIX_PROCESS_SNAPSHOT_ARGS, {
16781678timeoutMs: 5000,
16791679});
1680-const rows = parsePosixProcessRows(stdout);
1681-if (!rows) {
1680+const snapshot = parsePosixProcessRows(stdout);
1681+if (!snapshot) {
16821682return null;
16831683}
1684+const { malformedRows, rows } = snapshot;
16841685const selected = rows.find((row) => row.processId === safePid);
16851686if (!selected) {
16861687return null;
16871688}
1688-return formatPosixProcessTreeSample(selected, collectPosixProcessTree(rows, safePid));
1689+const treeRows = collectPosixProcessTree(rows, safePid);
1690+if (hasMalformedProcessTreeRows(malformedRows, treeRows)) {
1691+return null;
1692+}
1693+return formatPosixProcessTreeSample(selected, treeRows);
16891694} catch {
16901695return null;
16911696}
@@ -1700,13 +1705,16 @@ async function samplePosixProcessTree(pid, run, commandLineNeedles) {
17001705const { stdout } = await run("ps", POSIX_PROCESS_SNAPSHOT_ARGS, {
17011706timeoutMs: 5000,
17021707});
1703-const rows = parsePosixProcessRows(stdout);
1704-if (!rows) {
1708+const snapshot = parsePosixProcessRows(stdout);
1709+if (!snapshot) {
17051710return null;
17061711}
1707-const descendants = collectPosixProcessTree(rows, safePid).filter(
1708-(row) => row.processId !== safePid,
1709-);
1712+const { malformedRows, rows } = snapshot;
1713+const rootTreeRows = collectPosixProcessTree(rows, safePid);
1714+if (hasMalformedProcessTreeRows(malformedRows, rootTreeRows)) {
1715+return null;
1716+}
1717+const descendants = rootTreeRows.filter((row) => row.processId !== safePid);
17101718const commandMatches = descendants.filter((row) =>
17111719commandLineNeedles.every((needle) =>
17121720row.command.toLowerCase().includes(needle.toLowerCase()),
@@ -1736,6 +1744,7 @@ async function samplePosixProcessTree(pid, run, commandLineNeedles) {
1736174417371745function parsePosixProcessRows(stdout) {
17381746const rows = [];
1747+const malformedRows = [];
17391748for (const line of stdout.split(/\r?\n/u)) {
17401749const match = line.match(/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/u);
17411750if (!match) {
@@ -1754,7 +1763,11 @@ function parsePosixProcessRows(stdout) {
17541763!Number.isInteger(parentProcessId) ||
17551764!Number.isInteger(rssKb)
17561765) {
1757-return null;
1766+malformedRows.push({
1767+ pidRaw,
1768+ ppidRaw,
1769+});
1770+continue;
17581771}
17591772rows.push({
17601773 processId,
@@ -1764,7 +1777,7 @@ function parsePosixProcessRows(stdout) {
17641777command: command ?? "",
17651778});
17661779}
1767-return rows;
1780+return { malformedRows, rows };
17681781}
1769178217701783function parseStrictNonNegativeDecimal(raw) {
@@ -1820,6 +1833,32 @@ function collectPosixProcessTree(rows, rootPid) {
18201833return collected;
18211834}
182218351836+function hasMalformedProcessTreeRows(malformedRows, treeRows) {
1837+if (malformedRows.length === 0 || treeRows.length === 0) {
1838+return false;
1839+}
1840+const treePids = new Set(treeRows.map((row) => row.processId));
1841+return malformedRows.some(
1842+(row) =>
1843+rawProcessTokenMatchesTree(row.pidRaw, treePids) ||
1844+rawProcessTokenMatchesTree(row.ppidRaw, treePids),
1845+);
1846+}
1847+1848+function rawProcessTokenMatchesTree(raw, treePids) {
1849+const text = String(raw ?? "").trim();
1850+for (const pid of treePids) {
1851+const pidText = String(pid);
1852+if (text === pidText) {
1853+return true;
1854+}
1855+if (text.startsWith(pidText) && !/\d/u.test(text.at(pidText.length) ?? "")) {
1856+return true;
1857+}
1858+}
1859+return false;
1860+}
1861+18231862function selectPeakRssProcess(rows) {
18241863return rows.reduce((peak, row) => (peak && peak.rssKb >= row.rssKb ? peak : row), null);
18251864}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。