elvish/pkg/eval/builtin_fn_debug.go

109 lines
2.0 KiB
Go
Raw Normal View History

2018-02-03 14:12:13 +08:00
package eval
import (
"runtime"
"github.com/elves/elvish/pkg/parse"
2019-12-24 04:00:59 +08:00
"github.com/elves/elvish/pkg/util"
2018-02-03 14:12:13 +08:00
)
//elvdoc:fn src
//
// ```elvish
// src
// ```
//
// Output a map-like value describing the current source being evaluated. The value
// contains the following fields:
//
// - `name`, a unique name of the current source. If the source originates from a
// file, it is the full path of the file.
//
// - `code`, the full body of the current source.
//
// - `is-file`, whether the source originates from a file.
//
// Examples:
//
// ```elvish-transcript
// ~> put (src)[name code is-file]
// ▶ '[tty]'
// ▶ 'put (src)[name code is-file]'
// ▶ $false
// ~> echo 'put (src)[name code is-file]' > show-src.elv
// ~> elvish show-src.elv
// ▶ /home/elf/show-src.elv
// ▶ "put (src)[name code is-file]\n"
// ▶ $true
//
// Note: this builtin always returns information of the source of the function
// calling `src`. Consider the following example:
//
// ```elvish-transcript
// ~> echo 'fn show { put (src)[name] }' > ~/.elvish/lib/src-util.elv
// ~> use src-util
// ~> src-util:show
// ▶ /home/elf/.elvish/lib/src-util.elv
// ```
//elvdoc:fn -gc
//
// ```elvish
// -gc
// ```
//
// Force the Go garbage collector to run.
//
// This is only useful for debug purposes.
//elvdoc:fn -stack
//
// ```elvish
// -stack
// ```
//
// Print a stack trace.
//
// This is only useful for debug purposes.
//elvdoc:fn -log
//
// ```elvish
// -log $filename
// ```
//
// Direct internal debug logs to the named file.
//
// This is only useful for debug purposes.
2018-02-03 14:12:13 +08:00
func init() {
2018-02-07 03:39:40 +08:00
addBuiltinFns(map[string]interface{}{
"src": src,
"-gc": _gc,
"-stack": _stack,
"-log": _log,
2018-02-03 14:12:13 +08:00
})
}
func src(fm *Frame) parse.Source {
return fm.srcMeta
2018-02-03 14:12:13 +08:00
}
func _gc() {
2018-02-03 14:12:13 +08:00
runtime.GC()
}
func _stack(fm *Frame) {
out := fm.ports[1].File
// TODO(xiaq): Dup with main.go.
2018-02-03 14:12:13 +08:00
buf := make([]byte, 1024)
for runtime.Stack(buf, true) == cap(buf) {
buf = make([]byte, cap(buf)*2)
}
out.Write(buf)
}
func _log(fname string) error {
return util.SetOutputFile(fname)
2018-02-03 14:12:13 +08:00
}