From 78e4a40750565d8b19c7340abe584564f79bc32b Mon Sep 17 00:00:00 2001
From: Daniel <dhaavi@users.noreply.github.com>
Date: Wed, 28 Aug 2024 11:50:45 +0200
Subject: [PATCH] [service] Fix SPN build

---
 spn/debug.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 spn/debug.go

diff --git a/spn/debug.go b/spn/debug.go
new file mode 100644
index 00000000..824c41da
--- /dev/null
+++ b/spn/debug.go
@@ -0,0 +1,60 @@
+package spn
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"runtime"
+
+	"github.com/maruel/panicparse/v2/stack"
+
+	"github.com/safing/portmaster/base/utils/debug"
+	"github.com/safing/portmaster/service/mgr"
+)
+
+// GetWorkerInfo returns the worker info of all running workers.
+func (i *Instance) GetWorkerInfo() (*mgr.WorkerInfo, error) {
+	snapshot, _, err := stack.ScanSnapshot(bytes.NewReader(fullStack()), io.Discard, stack.DefaultOpts())
+	if err != nil && !errors.Is(err, io.EOF) {
+		return nil, fmt.Errorf("get stack: %w", err)
+	}
+
+	infos := make([]*mgr.WorkerInfo, 0, 32)
+	for _, m := range i.serviceGroup.Modules() {
+		wi, _ := m.Manager().WorkerInfo(snapshot) // Does not fail when we provide a snapshot.
+		infos = append(infos, wi)
+	}
+
+	return mgr.MergeWorkerInfo(infos...), nil
+}
+
+// AddWorkerInfoToDebugInfo adds the worker info of all running workers to the debug info.
+func (i *Instance) AddWorkerInfoToDebugInfo(di *debug.Info) {
+	info, err := i.GetWorkerInfo()
+	if err != nil {
+		di.AddSection(
+			"Worker Status Failed",
+			debug.UseCodeSection,
+			err.Error(),
+		)
+		return
+	}
+
+	di.AddSection(
+		fmt.Sprintf("Worker Status: %d/%d (%d?)", info.Running, len(info.Workers), info.Missing+info.Other),
+		debug.UseCodeSection,
+		info.Format(),
+	)
+}
+
+func fullStack() []byte {
+	buf := make([]byte, 8096)
+	for {
+		n := runtime.Stack(buf, true)
+		if n < len(buf) {
+			return buf[:n]
+		}
+		buf = make([]byte, 2*len(buf))
+	}
+}