// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package debug contains facilities for programs to debug themselves while
// they are running.
package debug

import (
	"internal/poll"
	"os"
	"runtime"
	_ "unsafe" // for linkname
)

// PrintStack prints to standard error the stack trace returned by runtime.Stack.
func PrintStack() {
	os.Stderr.Write(Stack())
}

// Stack returns a formatted stack trace of the goroutine that calls it.
// It calls [runtime.Stack] with a large enough buffer to capture the entire trace.
func Stack() []byte {
	buf := make([]byte, 1024)
	for {
		n := runtime.Stack(buf, false)
		if n < len(buf) {
			return buf[:n]
		}
		buf = make([]byte, 2*len(buf))
	}
}

// CrashOptions provides options that control the formatting of the
// fatal crash message.
type CrashOptions struct {
	/* for future expansion */
}

// SetCrashOutput configures a single additional file where unhandled
// panics and other fatal errors are printed, in addition to standard error.
// There is only one additional file: calling SetCrashOutput again overrides
// any earlier call.
// SetCrashOutput duplicates f's file descriptor, so the caller may safely
// close f as soon as SetCrashOutput returns.
// To disable this additional crash output, call SetCrashOutput(nil).
// If called concurrently with a crash, some in-progress output may be written
// to the old file even after an overriding SetCrashOutput returns.
func SetCrashOutput(f *os.File, opts CrashOptions) error {
	fd := ^uintptr(0)
	if f != nil {
		// The runtime will write to this file descriptor from
		// low-level routines during a panic, possibly without
		// a G, so we must call f.Fd() eagerly. This creates a
		// danger that that the file descriptor is no longer
		// valid at the time of the write, because the caller
		// (incorrectly) called f.Close() and the kernel
		// reissued the fd in a later call to open(2), leading
		// to crashes being written to the wrong file.
		//
		// So, we duplicate the fd to obtain a private one
		// that cannot be closed by the user.
		// This also alleviates us from concerns about the
		// lifetime and finalization of f.
		// (DupCloseOnExec returns an fd, not a *File, so
		// there is no finalizer, and we are responsible for
		// closing it.)
		//
		// The new fd must be close-on-exec, otherwise if the
		// crash monitor is a child process, it may inherit
		// it, so it will never see EOF from the pipe even
		// when this process crashes.
		//
		// A side effect of Fd() is that it calls SetBlocking,
		// which is important so that writes of a crash report
		// to a full pipe buffer don't get lost.
		fd2, _, err := poll.DupCloseOnExec(int(f.Fd()))
		if err != nil {
			return err
		}
		runtime.KeepAlive(f) // prevent finalization before dup
		fd = uintptr(fd2)
	}
	if prev := runtime_setCrashFD(fd); prev != ^uintptr(0) {
		// We use NewFile+Close because it is portable
		// unlike syscall.Close, whose parameter type varies.
		os.NewFile(prev, "").Close() // ignore error
	}
	return nil
}

//go:linkname runtime_setCrashFD runtime.setCrashFD
func runtime_setCrashFD(uintptr) uintptr
