// Copyright 2016 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.

// Traceback support for gccgo.
// The actual traceback code is written in C.

package runtime

import (
	"runtime/internal/sys"
	"unsafe"
)

// For gccgo, use go:linkname to rename compiler-called functions to
// themselves, so that the compiler will export them.
// These are temporary for C runtime code to call.
//go:linkname traceback runtime.traceback
//go:linkname printtrace runtime.printtrace
//go:linkname goroutineheader runtime.goroutineheader
//go:linkname printcreatedby runtime.printcreatedby

var (
	// initialized in tracebackinit
	runfinqPC        uintptr
	bgsweepPC        uintptr
	forcegchelperPC  uintptr
	timerprocPC      uintptr
	gcBgMarkWorkerPC uintptr
)

func tracebackinit() {
	// Go variable initialization happens late during runtime startup.
	// Instead of initializing the variables above in the declarations,
	// schedinit calls this function so that the variables are
	// initialized and available earlier in the startup sequence.
	// This doesn't use funcPC to avoid memory allocation.
	// FIXME: We should be able to use funcPC when escape analysis is on.
	f1 := runfinq
	runfinqPC = **(**uintptr)(unsafe.Pointer(&f1))
	f2 := bgsweep
	bgsweepPC = **(**uintptr)(unsafe.Pointer(&f2))
	f3 := forcegchelper
	forcegchelperPC = **(**uintptr)(unsafe.Pointer(&f3))
	f4 := timerproc
	timerprocPC = **(**uintptr)(unsafe.Pointer(&f4))
	f5 := gcBgMarkWorker
	gcBgMarkWorkerPC = **(**uintptr)(unsafe.Pointer(&f5))
}

func printcreatedby(gp *g) {
	// Show what created goroutine, except main goroutine (goid 1).
	pc := gp.gopc
	tracepc := pc // back up to CALL instruction for funcfileline.
	entry := funcentry(tracepc)
	if entry != 0 && tracepc > entry {
		tracepc -= sys.PCQuantum
	}
	function, file, line := funcfileline(tracepc, -1)
	if function != "" && showframe(function, gp) && gp.goid != 1 {
		print("created by ", function, "\n")
		print("\t", file, ":", line)
		if entry != 0 && pc > entry {
			print(" +", hex(pc-entry))
		}
		print("\n")
	}
}

// tracebackg is used to collect stack traces from other goroutines.
type tracebackg struct {
	gp     *g
	locbuf [_TracebackMaxFrames]location
	c      int
}

// location is a location in the program, used for backtraces.
type location struct {
	pc       uintptr
	filename string
	function string
	lineno   int
}

//extern runtime_callers
func c_callers(skip int32, locbuf *location, max int32, keepThunks bool) int32

// callers returns a stack trace of the current goroutine.
// The gc version of callers takes []uintptr, but we take []location.
func callers(skip int, locbuf []location) int {
	n := c_callers(int32(skip), &locbuf[0], int32(len(locbuf)), false)
	return int(n)
}

// traceback prints a traceback of the current goroutine.
// This differs from the gc version, which is given pc, sp, lr and g and
// can print a traceback of any goroutine.
func traceback(skip int32) {
	var locbuf [100]location
	c := c_callers(skip+1, &locbuf[0], int32(len(locbuf)), false)
	printtrace(locbuf[:c], getg())
}

// printtrace prints a traceback from locbuf.
func printtrace(locbuf []location, gp *g) {
	for i := range locbuf {
		if showframe(locbuf[i].function, gp) {
			print(locbuf[i].function, "\n\t", locbuf[i].filename, ":", locbuf[i].lineno, "\n")
		}
	}
}

// showframe returns whether to print a frame in a traceback.
// name is the function name.
func showframe(name string, gp *g) bool {
	g := getg()
	if g.m.throwing > 0 && gp != nil && (gp == g.m.curg || gp == g.m.caughtsig.ptr()) {
		return true
	}

	// Gccgo can trace back through C functions called via cgo.
	// We want to print those in the traceback.
	// But unless GOTRACEBACK > 1 (checked below), still skip
	// internal C functions and cgo-generated functions.
	if !contains(name, ".") && !hasprefix(name, "__go_") && !hasprefix(name, "_cgo_") {
		return true
	}

	level, _, _ := gotraceback()

	// Special case: always show runtime.gopanic frame, so that we can
	// see where a panic started in the middle of a stack trace.
	// See golang.org/issue/5832.
	// __go_panic is the current gccgo name.
	if name == "runtime.gopanic" || name == "__go_panic" {
		return true
	}

	return level > 1 || contains(name, ".") && (!hasprefix(name, "runtime.") || isExportedRuntime(name))
}

// isExportedRuntime reports whether name is an exported runtime function.
// It is only for runtime functions, so ASCII A-Z is fine.
func isExportedRuntime(name string) bool {
	const n = len("runtime.")
	return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
}

var gStatusStrings = [...]string{
	_Gidle:      "idle",
	_Grunnable:  "runnable",
	_Grunning:   "running",
	_Gsyscall:   "syscall",
	_Gwaiting:   "waiting",
	_Gdead:      "dead",
	_Gcopystack: "copystack",
}

func goroutineheader(gp *g) {
	gpstatus := readgstatus(gp)

	isScan := gpstatus&_Gscan != 0
	gpstatus &^= _Gscan // drop the scan bit

	// Basic string status
	var status string
	if 0 <= gpstatus && gpstatus < uint32(len(gStatusStrings)) {
		status = gStatusStrings[gpstatus]
	} else {
		status = "???"
	}

	// Override.
	if gpstatus == _Gwaiting && gp.waitreason != "" {
		status = gp.waitreason
	}

	// approx time the G is blocked, in minutes
	var waitfor int64
	if (gpstatus == _Gwaiting || gpstatus == _Gsyscall) && gp.waitsince != 0 {
		waitfor = (nanotime() - gp.waitsince) / 60e9
	}
	print("goroutine ", gp.goid, " [", status)
	if isScan {
		print(" (scan)")
	}
	if waitfor >= 1 {
		print(", ", waitfor, " minutes")
	}
	if gp.lockedm != nil {
		print(", locked to thread")
	}
	print("]:\n")
}

// isSystemGoroutine reports whether the goroutine g must be omitted in
// stack dumps and deadlock detector.
func isSystemGoroutine(gp *g) bool {
	// FIXME: This doesn't work reliably for gccgo because in many
	// cases the startpc field will be set to a thunk rather than
	// to one of these addresses.
	pc := gp.startpc
	return pc == runfinqPC && !fingRunning ||
		pc == bgsweepPC ||
		pc == forcegchelperPC ||
		pc == timerprocPC ||
		pc == gcBgMarkWorkerPC
}

func tracebackothers(me *g) {
	var tb tracebackg
	tb.gp = me

	// The getTraceback function will modify me's stack context.
	// Preserve it in case we have been called via systemstack.
	context := me.context
	stackcontext := me.stackcontext

	level, _, _ := gotraceback()

	// Show the current goroutine first, if we haven't already.
	g := getg()
	gp := g.m.curg
	if gp != nil && gp != me {
		print("\n")
		goroutineheader(gp)
		gp.traceback = &tb
		getTraceback(me, gp)
		printtrace(tb.locbuf[:tb.c], nil)
		printcreatedby(gp)
	}

	lock(&allglock)
	for _, gp := range allgs {
		if gp == me || gp == g.m.curg || readgstatus(gp) == _Gdead || isSystemGoroutine(gp) && level < 2 {
			continue
		}
		print("\n")
		goroutineheader(gp)

		// gccgo's only mechanism for doing a stack trace is
		// _Unwind_Backtrace.  And that only works for the
		// current thread, not for other random goroutines.
		// So we need to switch context to the goroutine, get
		// the backtrace, and then switch back.
		//
		// This means that if g is running or in a syscall, we
		// can't reliably print a stack trace.  FIXME.

		// Note: gp.m == g.m occurs when tracebackothers is
		// called from a signal handler initiated during a
		// systemstack call. The original G is still in the
		// running state, and we want to print its stack.
		if gp.m != g.m && readgstatus(gp)&^_Gscan == _Grunning {
			print("\tgoroutine running on other thread; stack unavailable\n")
			printcreatedby(gp)
		} else if readgstatus(gp)&^_Gscan == _Gsyscall {
			print("\tgoroutine in C code; stack unavailable\n")
			printcreatedby(gp)
		} else {
			gp.traceback = &tb
			getTraceback(me, gp)
			printtrace(tb.locbuf[:tb.c], nil)
			printcreatedby(gp)
		}
	}
	unlock(&allglock)

	me.context = context
	me.stackcontext = stackcontext
}
