OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git commits / 23f25e1

Fix double-free: skip Hyperswarm teardown, just process.exit()
The native double-free crash is in libudx/SecretStream teardown during Hyperswarm.destroy(). Not our code — it's a libudx bug. git-remote-punch is a short-lived process (spawned per git operation). The OS reclaims all sockets, file descriptors, and memory on process exit. Graceful teardown is unnecessary and triggers the native crash. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
23f25e1265aacfad3d32db23562edfe9eb129194
by plankatron <fleeky@gmail.com> · 2026-04-07T13:57:37.000Z

Changed files (1) +4 -10

bin/git-remote-punch +4 -10
……@@ -172,16 +172,10 @@ async function handleConnect(service, serverKey, repoName, httpsUrl, stdout, std
172172 function cleanup (code) {
173173 if (cleaningUp) return
174174 cleaningUp = true
175 // Hard kill safety — if async teardown hangs, don't spin forever
176 const hardKill = setTimeout(() => process.exit(code), 5000)
177 hardKill.unref()
178 // Don't destroy conn if already destroyed — double-destroy triggers
179 // native double-free in libudx/SecretStream teardown.
180 if (!conn.destroyed) try { conn.destroy() } catch {}
181 connector.destroy().catch(() => {}).finally(() => {
182 clearTimeout(hardKill)
183 process.exit(code)
184 })
175 // Skip async teardown — just exit. The OS reclaims all resources.
176 // Hyperswarm/libudx teardown has a native double-free bug that
177 // crashes the process during conn.destroy() or swarm.destroy().
178 process.exit(code)
185179 }
186180
187181 // Manual bidirectional forwarding — NOT pipe()!