go-delve/delve · error

setpgid

Error message

setpgid

What it means

fork_exec in the native macOS backend prints this via perror and exits when setpgid(0,0) fails while the child process is being prepared for debugging. The child must become its own process group so the debugger can deliver signals to it independently; failing here aborts the debuggee before exec, causing process launch to fail.

Source

Thrown at pkg/proc/native/exec_darwin.c:69

		if (n != 0) {
			// Child died, reap it.
			waitpid(pid, NULL, 0);
			return -1;
		}
		return pid;
	}

	// Fork succeeded, we are in the child.
	int pret, cret;
	char sig;

	close(fd[1]);
	read(fd[0], &sig, 1);
	close(fd[0]);

	// Create a new process group.
	if (setpgid(0, 0) < 0) {
		perror("setpgid");
		exit(1);
	}

	// Set errno to zero before a call to ptrace.
	// It is documented that ptrace can return -1 even
	// for successful calls.
	errno = 0;
	pret = ptrace(PT_TRACE_ME, 0, 0, 0);
	if (pret != 0 && errno != 0) {
		perror("ptrace");
		exit(1);
	}

	// Change working directory if wd is not empty.
	if (wd && wd[0]) {
		errno = 0;
		cret = chdir(wd);
		if (cret != 0 && errno != 0) {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Check that the parent environment permits process-group creation (run delve from a normal shell/terminal rather than a heavily sandboxed context).
  2. Inspect errno context on the machine (dmesg/sandbox logs) and any macOS security policies (SIP, MDM, sandbox profiles) blocking setpgid.
  3. Ensure your macOS/SDK versions match what your delve build supports; rebuild delve with a current Xcode toolchain.
  4. As a workaround, attach to an already-running process (dlv attach) instead of fork/exec launch.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: ensure the environment allows creating process groups
if err := syscall.Setpgid(0, 0); err != nil {
	return fmt.Errorf("environment forbids setpgid: %w", err)
}
// restore group if needed by your harness

Type guard

func isExecLaunchFailure(err error) bool {
	return err != nil && strings.Contains(err.Error(), "setpgid")
}

Try / catch

err := dlvClient.Launch(ctx, prog, args)
if err != nil && strings.Contains(err.Error(), "setpgid") {
	log.Printf("fork/exec launch blocked (setpgid): %v — try dlv attach or a less restricted environment", err)
	return fallbackToAttach()
}

Prevention

When it happens

Trigger: Launching a program with dlv (native backend) on macOS when the child's setpgid(0,0) system call fails, typically due to session/process-group restrictions of the parent (e.g. job-control restrictions, restricted sandbox, or a process-group ID race).

Common situations: Launching delve from restricted environments (containers without proper process APIs, sandboxed IDE terminals); extremely resource-constrained systems; EPERM/EACCES from a hardened runtime or security agent.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/9d78c9e7902dae04. Report an issue: GitHub.