Skip to content

[Code Quality] ProcessKiller.KillProcessTreeAndParents — calls Toolhelp32 snapshot twice per invocation (BuildProcessSnapshotNative + BuildParentChildMapNative) #1059

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity: Info

File

src/Servy.Core/Helpers/ProcessKiller.cs

Lines

217 + 219, 270 + 287

Issue

Both overloads of KillProcessTreeAndParents call two separate native snapshot enumerations of the entire system process table:

// Line 217-219 — KillProcessTreeAndParents(string processName, ...)
var completeSnapshot = BuildProcessSnapshotNative();   // CreateToolhelp32Snapshot + Process32First/Next over all PIDs
var protectedPids    = GetAncestorPids(completeSnapshot);
var byParent         = BuildParentChildMapNative();    // CreateToolhelp32Snapshot + Process32First/Next over all PIDs (again!)

BuildProcessSnapshotNative returns Dictionary<int, ProcessInfoNode> { ParentId, Name }, while BuildParentChildMapNative returns Dictionary<int, List<int>> (parent → children). Both are derived from the same PROCESSENTRY32 rows — they could be built in a single pass.

On a busy server with 500+ processes this is a measurable redundant native call (CreateToolhelp32Snapshot itself is non-trivial under load) and during process-kill work it widens the race window between the two snapshots — they may disagree about which PIDs exist, causing KillParentProcesses to refuse a parent that WalkAndKillChildren is also trying to handle.

Suggested fix

Add a single BuildSnapshot (or extend BuildProcessSnapshotNative) that returns both maps from one Toolhelp32 walk:

private (Dictionary<int, ProcessInfoNode> snapshot, Dictionary<int, List<int>> byParent)
    BuildSnapshotAndChildMap()
{
    // single CreateToolhelp32Snapshot pass, populate both
}

Then have KillProcessTreeAndParents consume both from one call instead of issuing two snapshots.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions