From 59061ae2a0f9ac82567642215c0e3f06da7d0a0a Mon Sep 17 00:00:00 2001 From: Bot Date: Sun, 22 Mar 2026 17:39:03 +0530 Subject: [PATCH 1/3] =?UTF-8?q?perf(process):=20build=20snapshot=20map=20o?= =?UTF-8?q?nce=20on=20Windows=20to=20fix=20O(N=C2=B2)=20process=20listing?= =?UTF-8?q?=20(#818)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- process/process_windows.go | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/process/process_windows.go b/process/process_windows.go index a1e28be698..633a1c1665 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -321,6 +321,9 @@ func (p *Process) PpidWithContext(_ context.Context) (int32, error) { } func (p *Process) NameWithContext(ctx context.Context) (string, error) { + if p.name != "" { + return p.name, nil + } if p.Pid == 0 { return "System Idle Process", nil } @@ -587,6 +590,9 @@ func (p *Process) NumFDsWithContext(_ context.Context) (int32, error) { } func (p *Process) NumThreadsWithContext(_ context.Context) (int32, error) { + if p.numThreads != 0 { + return p.numThreads, nil + } ppid, ret, _, err := getFromSnapProcess(p.Pid) if err != nil { return 0, err @@ -598,6 +604,8 @@ func (p *Process) NumThreadsWithContext(_ context.Context) (int32, error) { p.setPpid(ppid) } + p.numThreads = ret + return ret, nil } @@ -900,6 +908,29 @@ func getFromSnapProcess(pid int32) (int32, int32, string, error) { //nolint:unpa return 0, 0, "", fmt.Errorf("couldn't find pid: %d", pid) } +func buildSnapProcessMap() (map[uint32]windows.ProcessEntry32, error) { + snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0) + if err != nil { + return nil, err + } + defer windows.CloseHandle(snap) + + var pe32 windows.ProcessEntry32 + pe32.Size = uint32(unsafe.Sizeof(pe32)) + if err = windows.Process32First(snap, &pe32); err != nil { + return nil, err + } + + snapMap := make(map[uint32]windows.ProcessEntry32) + for { + snapMap[pe32.ProcessID] = pe32 + if err = windows.Process32Next(snap, &pe32); err != nil { + break + } + } + return snapMap, nil +} + func ProcessesWithContext(ctx context.Context) ([]*Process, error) { out := []*Process{} @@ -908,11 +939,23 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) { return out, fmt.Errorf("could not get Processes %w", err) } + snapMap, err := buildSnapProcessMap() + if err != nil { + return nil, err + } + for _, pid := range pids { p, err := NewProcessWithContext(ctx, pid) if err != nil { continue } + + if entry, ok := snapMap[uint32(pid)]; ok { + p.name = windows.UTF16ToString(entry.ExeFile[:]) + p.setPpid(int32(entry.ParentProcessID)) + p.numThreads = int32(entry.Threads) + } + out = append(out, p) } From d88b333908e854a503ffa2a843e56110a72e700d Mon Sep 17 00:00:00 2001 From: Bot Date: Sun, 22 Mar 2026 17:49:33 +0530 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20address=20Copilot=20review=20?= =?UTF-8?q?=E2=80=94=20ERROR=5FNO=5FMORE=5FFILES=20handling,=20error=20wra?= =?UTF-8?q?pping,=20NameWithContext=20cache=20write-back?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- process/process_windows.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/process/process_windows.go b/process/process_windows.go index 633a1c1665..caa4f6a9f8 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -336,7 +336,9 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { return "", fmt.Errorf("could not get Name: %w", err) } - return filepath.Base(exe), nil + name := filepath.Base(exe) + p.name = name + return name, nil } func (*Process) TgidWithContext(_ context.Context) (int32, error) { @@ -925,7 +927,10 @@ func buildSnapProcessMap() (map[uint32]windows.ProcessEntry32, error) { for { snapMap[pe32.ProcessID] = pe32 if err = windows.Process32Next(snap, &pe32); err != nil { - break + if err == windows.ERROR_NO_MORE_FILES { + break + } + return nil, err } } return snapMap, nil @@ -941,7 +946,7 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) { snapMap, err := buildSnapProcessMap() if err != nil { - return nil, err + return out, fmt.Errorf("could not build process snapshot: %w", err) } for _, pid := range pids { From 0b872e34bbe5c213af6a4e93487921e2eac445e8 Mon Sep 17 00:00:00 2001 From: Bot Date: Sun, 22 Mar 2026 18:02:07 +0530 Subject: [PATCH 3/3] fix(linter): address errorlint and gocritic warnings in buildSnapProcessMap --- process/process_windows.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/process/process_windows.go b/process/process_windows.go index caa4f6a9f8..56de6f173a 100644 --- a/process/process_windows.go +++ b/process/process_windows.go @@ -919,15 +919,15 @@ func buildSnapProcessMap() (map[uint32]windows.ProcessEntry32, error) { var pe32 windows.ProcessEntry32 pe32.Size = uint32(unsafe.Sizeof(pe32)) - if err = windows.Process32First(snap, &pe32); err != nil { + if err := windows.Process32First(snap, &pe32); err != nil { return nil, err } snapMap := make(map[uint32]windows.ProcessEntry32) for { snapMap[pe32.ProcessID] = pe32 - if err = windows.Process32Next(snap, &pe32); err != nil { - if err == windows.ERROR_NO_MORE_FILES { + if err := windows.Process32Next(snap, &pe32); err != nil { + if errors.Is(err, windows.ERROR_NO_MORE_FILES) { break } return nil, err