feat(v3): debug package + user-goroutine panic handling#5173
Draft
leaanthony wants to merge 8 commits intomasterfrom
Draft
feat(v3): debug package + user-goroutine panic handling#5173leaanthony wants to merge 8 commits intomasterfrom
leaanthony wants to merge 8 commits intomasterfrom
Conversation
Demonstrates funnelling panics from user-spawned goroutines through the same PanicHandler wails uses for bound methods and internal runtime callbacks. Ships a recoverAndReport() helper for deferral inside user goroutines, since wails cannot inject deferred recovers into code it does not own. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The existing guide noted that user-spawned goroutines fall outside wails' automatic recovery but didn't show how to route them through the registered PanicHandler. Added a "Handling Panics in Your Own Goroutines" section with the recoverAndReport pattern, a caution on stack-trace fidelity, and a link to the new runnable example. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The guide referenced v3/examples/panic-handling just above the new section and then added a second reference to v3/examples/user-panic-handling, making it unclear which one to run. Moved the references into a single list inside the "Handling Panics in Your Own Goroutines" section with a one-line description of what each example demonstrates. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tform build collect_windows.go: writeCoreDump now writes a real minidump of the current process via Dbghelp.MiniDumpWriteDump, using the GetCurrentProcess pseudo- handle so no SeDebugPrivilege or OpenProcess is required — runs under a standard user token. Default path uses os.TempDir() with a wails-crash-<pid>- <unix>.dmp filename. Flags combine MiniDumpNormal, WithThreadInfo, WithHandleData, and WithUnloadedModules — rich postmortem content without writing the full address space. Signature change: writeCoreDump(path string) (string, error). Returns the absolute dump path so callers can attach it to reports without reading megabytes back into Go memory. collect_unix.go: fix compile errors (double init in if-stmt, MemorySummary composite literal using non-existent HeapAlloc/HeapObjects fields, runtime.MemStats field name TotalPause → PauseTotalNs, LastGC narrowing to uint32). Unix writeCoreDump matches the new signature and returns an unimplemented error. debug.go + types.go: add `doctor` import alias for pkg/doctor-ng (package is doctorng; code references as doctor.*). Verified: go build ./pkg/debug/... on linux, windows, and darwin all green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…bug guide
Replace the old Collector / Run() façade with two top-level, stateless
entry points and functional options:
- debug.Dump(...) writes a minidump of the current process.
Options: WithPath, WithFullMemory.
Windows only; returns an error on other platforms.
- debug.Report(...) collects system, build, process/memory/module,
and diagnostic info. Opt-in minidump via WithDump, WithDumpPath,
or WithDumpFullMemory. Returns a *CrashReport with a DumpPath
field populated only when a dump was requested.
Neither entry point is invoked automatically by wails — PanicHandler
integration is opt-in so crash reporting can be gated on user consent
or PII redaction.
Tests:
- debug_test.go covers Report population, default DumpPath empty,
non-Windows Dump returns an error, option composition.
- dump_windows_test.go (//go:build windows) verifies Dump produces
a file with the MDMP magic bytes, default path lands under TempDir,
and Report(WithDumpPath) records the dump path.
Docs:
- docs/src/content/docs/guides/debugging-crashes.mdx — full guide
covering quick reference, CrashReport fields, PanicHandler
integration, manual debugging use cases, minidump flag rationale,
non-Windows behaviour, and security notes.
- docs/src/content/docs/guides/panic-handling.mdx — cross-link into
the new guide from the PanicHandler section.
Build verified on linux, windows, darwin. go test ./pkg/debug/... green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
added 2 commits
April 21, 2026 19:13
- Fix MemorySummary.TotalVirtual: use OS-level memory APIs instead of incorrect TotalAlloc+Mallocs (psapi GetProcessMemoryInfo on Windows, /proc/self/status VmSize on Linux) - Implement loadModules on Windows using CreateToolhelp32Snapshot (Module32First/Next) for proper module enumeration - Implement collectThreadInfo on Windows using CreateToolhelp32Snapshot (Thread32First/Next) for thread counting - Remove dead ThreadInfo.WaitChan chan field, replace with WaitReason string that properly serializes to JSON - Add process handle counting via GetProcessHandleCount on Windows - Add comprehensive tests for memory, modules, threads, and JSON round-trip on both platforms
- Split collect_unix.go build tag from '!windows' to 'linux' since /proc only exists on Linux, not macOS - Add collect_darwin.go with Go runtime fallbacks for macOS - Remove omitempty from ThreadInfo.WaitReason so the field always appears in JSON serialization - Fix tests to account for platform differences: - Module enumeration only tested on Linux and Windows - Thread count only asserted on Linux and Windows - MemoryBytes only asserted on Linux - All platforms still test MemorySummary non-zero (via Go runtime)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Introduces a Windows-first diagnostic/crash-dump package alongside guidance
and an example for handling panics in user-spawned goroutines.
New:
v3/pkg/debugA small, stateless API for capturing crash diagnostics at runtime. Two
entry points:
debug.Dump(...)— writes a Windows minidump of the current process viaDbghelp.MiniDumpWriteDump. UsesGetCurrentProcess()so noelevation / SeDebugPrivilege is required — runs under a standard user
token. Returns the absolute path of the written file. On non-Windows
platforms it returns a clean unimplemented error so callers can degrade
gracefully. Options:
WithPath,WithFullMemory.debug.Report(...)— collects system info, build info, runtimeprocess/memory/module state, and a diagnostics pass from
pkg/doctor-ng. Returns a*CrashReport. Minidump is opt-in viaWithDump/WithDumpPath/WithDumpFullMemory.Both entry points are designed to be safe to call from
PanicHandler:they stream the minidump directly to a file handle (no Go-side buffering
of megabytes), and
Reportreturns a partial report even when theminidump step fails.
Default dump location is
os.TempDir()— on Windows,%LOCALAPPDATA%\Temp\wails-crash-<pid>-<unix>.dmp. Writable by thecurrent user, not elevated, not world-readable.
New:
v3/examples/user-panic-handlingDemonstrates funnelling panics from user-spawned goroutines through
the same
PanicHandlerwails uses for bound methods. Ships arecoverAndReport()helper that user code defers at the top of everygoroutine it owns. Without it, goroutine panics crash the whole process —
wails can only inject deferred recovers into code paths it owns.
Docs
guides/debugging-crashes.mdx— full coverage of thedebug package. Quick reference,
CrashReportshape,PanicHandlerintegration, manual debugging use cases (hang detection, support
bundles, anomaly reports), minidump flag rationale, non-Windows
behaviour, and security notes.
guides/panic-handling.mdx— new "Handling Panics in YourOwn Goroutines" section with the
recoverAndReportpattern, and a"Capturing Diagnostics on Panic" section cross-linking into the new
debug guide.
Security notes
SeDebugPrivilege. NoOpenProcesson remote PIDs.Deliberately scoped to the calling process.
data. The docs call this out so consumers handle dumps with the same
care as raw memory images.
Test plan
go build ./v3/pkg/debug/...on linux, windows, darwin (verified locally)go vet ./v3/pkg/debug/...clean on all three platformsgo test ./v3/pkg/debug/...passes on linuxReportpopulates fields, defaultDumpPathempty withoutWithDump,Dumpreturns error onnon-Windows, option composition
dump_windows_test.goon a real Windows host — verifiesMDMP magic bytes, default path under
TempDir,Report(WithDumpPath)writes + records path
.dmpin WinDbg to sanity-check thread/handle/modulecoverage with the default flag set
Out of scope (follow-ups)
debug.ReportintoPanicHandlerby default — intentionallyopt-in. Could ship a helper
debug.CrashHandler(userHandler)later.GOTRACEBACK=crash,CrashReporter,
rr, etc.) — out of scope for a Windows-first package.🤖 Generated with Claude Code