Browse Source

runtime: allow panic on syscall.Exit instead of halting

In some environments, such as u-root, code can be imported which
provides a shell. The shell calls functions, instead of trying
to use exec.Command (which is not available). An example
can be found in github.com:u-root/u-root/tools/tinygobb.

When the command exits, the shell needs to resume operation,
which is not possible when runtime.Exit calls halt.

On tamago, we achieve this by setting a normally nil
function, runtime.Exit, to a funtion which panics. The
shell has a recover() to catch the panics.

There are many ways in which setting runtime.Exit can go wrong,
including different functions setting it to different functions.

tinygo allows a simpler, and hence more robust, model: instead
of halting, we can panic. But in most cases, halting is ok.

Add a function, runtime.PanicOnExit, which enables a panic
on exit. This function is idempotent, and once panic on exit
is enabled, it can not be disabled. This is restrictive
by design. It is hoped that by making it simple and non-revocable,
we can avoid the problems that can occur with more complex
mechanisms, but still provide an option to halting.

A function is provided, instead of just a variable, to allow
simpler access from assembly, i.e., both variables and
functions have been used in bare metal environments and, for
several reasons, functions have proved more flexible.

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
pull/4010/head
Ronald G. Minnich 12 months ago
parent
commit
583411a057
  1. 23
      src/runtime/baremetal.go

23
src/runtime/baremetal.go

@ -3,6 +3,7 @@
package runtime
import (
"internal/itoa"
"unsafe"
)
@ -59,8 +60,30 @@ func runtime_putchar(c byte) {
putchar(c)
}
// ErrExitPanic implements error
type ErrExitPanic int
func (e ErrExitPanic) Error() string {
return "errno " + itoa.Itoa(int(e))
}
var panicOnExit bool
// PanicOnExit enables panic when syscall.Exit is called,
// as opposed to halting. It can be set by, e.g., a u-root
// shell to regain control when commands exit.
// This in turn makes it easier for building unmodified
// commands into u-root, for bare metal environments.
func PanicOnExit() {
panicOnExit = true
}
//go:linkname syscall_Exit syscall.Exit
func syscall_Exit(code int) {
if panicOnExit {
panic(ErrExitPanic(code))
}
exit(code)
}

Loading…
Cancel
Save