Go has added Valgrind support

Motivation and Scope of Go’s Valgrind Support

  • Change primarily added to test constant‑time behavior of crypto code by abusing Valgrind’s uninitialized‑memory tracking, following the “ctgrind” technique.
  • Secondary goal: inspect Go runtime’s memory handling and potentially expose subtle bugs.
  • Support is currently experimental; instrumentation may be incomplete and can produce spurious warnings.
  • Implemented via a small assembly shim that emits Valgrind client‑request instructions, avoiding cgo and embedding headers.

GC, Memory Leaks, and Profiling Pain Points

  • Multiple commenters report “memory pressure” in long‑running Go services: RSS grows over time and only restarts recover memory, even without classic leaks.
  • Common leak/pressure patterns in Go:
    • Goroutines without clear shutdown criteria.
    • Slices that reference large backing arrays (e.g., sub‑slices of big file buffers).
    • Long‑lived references (maps/caches, captured pointers, interior pointers) keeping large graphs alive.
    • Fragmentation in a non‑moving GC.
  • Frustration that Go’s GC doesn’t expose GC roots or reference chains directly; people want tools to answer “who is keeping this alive?”.
  • Tools mentioned: pprof (good but not enough for some leak cases), goref (heap‑dump based reference tracing), GOMEMLIMIT for constraining memory.

What Valgrind Adds vs Existing Go Tooling

  • Valgrind suite can detect:
    • Use of uninitialized memory, invalid reads/writes, and classic leaks (especially in cgo/unsafe code).
    • Memory usage over time (massif), cache and call behavior (cachegrind/callgrind).
  • Some argue pprof and Go’s built‑in asan/msan/tsan already cover many needs for pure Go; others see Valgrind as a “hidden super‑power” for tricky bugs and for C/C++ dependencies.

Limitations and Practical Concerns

  • In GC languages, leaks via still‑reachable but logically dead objects aren’t something Valgrind can “magically” decide are wrong; it mainly shows what’s still live at exit and where it came from.
  • Large existing native stacks (Python, Qt, etc.) can overwhelm Valgrind with noise; suppressions are often required.
  • Valgrind is slow due to CPU emulation, but doesn’t require recompilation or special builds.

Ecosystem and Language Comparisons

  • Some see needing Valgrind as a sign of weakness versus Rust, where unsafe and FFI are more constrained; others reply that any ecosystem using C/unsafe benefits from Valgrind.
  • There is meta‑discussion about persistent Go‑vs‑Rust comparisons and community tone, but consensus that Valgrind support is a net positive.