{"record":{"id":"4c8b9000246653bf","repo":"sipeed/picoclaw","slug":"error-in-syscall-dup2-v","errorCode":null,"errorMessage":"error in syscall.Dup2: %v","messagePattern":"error in syscall\\.Dup2: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/logger/panic_unix.go","lineNumber":19,"sourceCode":"//go:build !windows\n\npackage logger\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc initPanicFile(panicFile string) io.WriteCloser {\n\tfile, err := os.OpenFile(panicFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND|os.O_SYNC, 0o600)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"error in open panic: %v\", err))\n\t}\n\tif err = unix.Dup2(int(file.Fd()), int(os.Stderr.Fd())); err != nil {\n\t\tpanic(fmt.Sprintf(\"error in syscall.Dup2: %v\", err))\n\t}\n\treturn file\n}\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/logger/panic_unix.go#L1-L23","documentation":"Startup panic in the unix build: after successfully creating the panic log file, unix.Dup2(file.Fd(), os.Stderr.Fd()) failed while redirecting stderr onto the panic file so runtime panics are captured there. Dup2 of fd 2 essentially only fails when fd 2 is not an open descriptor (process launched with stderr closed, e.g. 2>&-) or the syscall is blocked by a sandbox/seccomp policy.","triggerScenarios":"Service launched with stderr closed (2>&- in shell/supervisor configs, or an exec harness that closes all standard fds); seccomp/container profiles denying dup2; os.Stderr.Fd() not a valid open descriptor in the runtime environment.","commonSituations":"'Clean' daemonizer scripts and minimal containers that close std fds instead of redirecting to /dev/null; hardened sandboxes; init templates using 2>&-.","solutions":["Change the launch configuration: redirect stderr to a file or /dev/null (2>/dev/null) instead of closing it (2>&-)","If sandboxed, permit dup2 in the seccomp/AppArmor profile","Verify fd 2 exists before launch: ls -l /proc/<pid>/fd/2"],"exampleFix":"# before\n./launcher 2>&-\n\n# after\n./launcher 2>/dev/null","handlingStrategy":"validation","validationCode":"if _, err := unix.FcntlInt(uintptr(os.Stderr.Fd()), unix.F_GETFD, 0); err != nil {\n    return errors.New(\"fd 2 closed; redirect stderr to /dev/null instead of closing it\")\n}","typeGuard":null,"tryCatchPattern":"Pre-main crash: handle at the supervisor level. Treat an immediate exit with this message as a launcher-configuration bug (closed stderr) and fix the launch line, not the code.","preventionTips":["Never launch services with 2>&-; use 2>/dev/null","Keep standard fds open (even to /dev/null) in unit files and containers","Smoke-test startup once under the exact production launcher configuration"],"tags":["logger","panic","unix","dup2","stderr","syscall","startup"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}