logging: avoids logging activity to stdio file descriptors (#1007)
This avoids logging activity on stdio file descriptors, in order to help make troubleshooting easier. Usually, there isn't an issue in these, yet wasm panics are harder to read if there is also logging of the .. logging. Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
// newJsGlobal = js.Global() // js.go init
|
||||
func newJsGlobal(rt http.RoundTripper) *jsVal {
|
||||
var fetchProperty interface{} = undefined
|
||||
var fetchProperty interface{} = goos.Undefined
|
||||
if rt != nil {
|
||||
fetchProperty = goos.RefHttpFetch
|
||||
}
|
||||
@@ -19,7 +19,7 @@ func newJsGlobal(rt http.RoundTripper) *jsVal {
|
||||
"crypto": jsCrypto,
|
||||
"Uint8Array": uint8ArrayConstructor,
|
||||
"fetch": fetchProperty,
|
||||
"AbortController": undefined,
|
||||
"AbortController": goos.Undefined,
|
||||
"Headers": headersConstructor,
|
||||
"process": jsProcess,
|
||||
"fs": jsfs,
|
||||
|
||||
@@ -90,7 +90,7 @@ type jsfsOpen struct{}
|
||||
func (jsfsOpen) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
path := args[0].(string)
|
||||
flags := toUint64(args[1]) // flags are derived from constants like oWRONLY
|
||||
perm := toUint32(args[2])
|
||||
perm := goos.ValueToUint32(args[2])
|
||||
callback := args[3].(funcWrapper)
|
||||
|
||||
fsc := mod.(*wasm.CallContext).Sys.FS()
|
||||
@@ -146,7 +146,7 @@ type jsfsFstat struct{}
|
||||
func (jsfsFstat) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
fsc := mod.(*wasm.CallContext).Sys.FS()
|
||||
|
||||
fd := toUint32(args[0])
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
callback := args[1].(funcWrapper)
|
||||
|
||||
fstat, err := syscallFstat(fsc, fd)
|
||||
@@ -231,7 +231,7 @@ type jsfsClose struct{}
|
||||
func (jsfsClose) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
fsc := mod.(*wasm.CallContext).Sys.FS()
|
||||
|
||||
fd := toUint32(args[0])
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
callback := args[1].(funcWrapper)
|
||||
|
||||
err := fsc.CloseFile(fd)
|
||||
@@ -246,13 +246,13 @@ func (jsfsClose) invoke(ctx context.Context, mod api.Module, args ...interface{}
|
||||
type jsfsRead struct{}
|
||||
|
||||
func (jsfsRead) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
fd := toUint32(args[0])
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
buf, ok := args[1].(*byteArray)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("arg[1] is %v not a []byte", args[1])
|
||||
}
|
||||
offset := toUint32(args[2])
|
||||
byteCount := toUint32(args[3])
|
||||
offset := goos.ValueToUint32(args[2])
|
||||
byteCount := goos.ValueToUint32(args[3])
|
||||
fOffset := args[4] // nil unless Pread
|
||||
callback := args[5].(funcWrapper)
|
||||
|
||||
@@ -297,13 +297,13 @@ func syscallRead(mod api.Module, fd uint32, offset interface{}, p []byte) (n uin
|
||||
type jsfsWrite struct{}
|
||||
|
||||
func (jsfsWrite) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
fd := toUint32(args[0])
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
buf, ok := args[1].(*byteArray)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("arg[1] is %v not a []byte", args[1])
|
||||
}
|
||||
offset := toUint32(args[2])
|
||||
byteCount := toUint32(args[3])
|
||||
offset := goos.ValueToUint32(args[2])
|
||||
byteCount := goos.ValueToUint32(args[3])
|
||||
fOffset := args[4] // nil unless Pread
|
||||
callback := args[5].(funcWrapper)
|
||||
|
||||
@@ -418,7 +418,7 @@ type jsfsMkdir struct{}
|
||||
|
||||
func (jsfsMkdir) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
path := args[0].(string)
|
||||
perm := toUint32(args[1])
|
||||
perm := goos.ValueToUint32(args[1])
|
||||
callback := args[2].(funcWrapper)
|
||||
|
||||
fsc := mod.(*wasm.CallContext).Sys.FS()
|
||||
@@ -502,7 +502,7 @@ type jsfsChmod struct{}
|
||||
|
||||
func (jsfsChmod) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
path := args[0].(string)
|
||||
mode := toUint32(args[1])
|
||||
mode := goos.ValueToUint32(args[1])
|
||||
callback := args[2].(funcWrapper)
|
||||
|
||||
_, _ = path, mode // TODO
|
||||
@@ -517,8 +517,8 @@ func (jsfsChmod) invoke(ctx context.Context, mod api.Module, args ...interface{}
|
||||
type jsfsFchmod struct{}
|
||||
|
||||
func (jsfsFchmod) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
fd := toUint32(args[0])
|
||||
mode := toUint32(args[1])
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
mode := goos.ValueToUint32(args[1])
|
||||
callback := args[2].(funcWrapper)
|
||||
|
||||
_, _ = fd, mode // TODO
|
||||
@@ -534,8 +534,8 @@ type jsfsChown struct{}
|
||||
|
||||
func (jsfsChown) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
path := args[0].(string)
|
||||
uid := toUint32(args[1])
|
||||
gid := toUint32(args[2])
|
||||
uid := goos.ValueToUint32(args[1])
|
||||
gid := goos.ValueToUint32(args[2])
|
||||
callback := args[3].(funcWrapper)
|
||||
|
||||
_, _, _ = path, uid, gid // TODO
|
||||
@@ -550,9 +550,9 @@ func (jsfsChown) invoke(ctx context.Context, mod api.Module, args ...interface{}
|
||||
type jsfsFchown struct{}
|
||||
|
||||
func (jsfsFchown) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
fd := toUint32(args[0])
|
||||
uid := toUint32(args[1])
|
||||
gid := toUint32(args[2])
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
uid := goos.ValueToUint32(args[1])
|
||||
gid := goos.ValueToUint32(args[2])
|
||||
callback := args[3].(funcWrapper)
|
||||
|
||||
_, _, _ = fd, uid, gid // TODO
|
||||
@@ -568,8 +568,8 @@ type jsfsLchown struct{}
|
||||
|
||||
func (jsfsLchown) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
path := args[0].(string)
|
||||
uid := toUint32(args[1])
|
||||
gid := toUint32(args[2])
|
||||
uid := goos.ValueToUint32(args[1])
|
||||
gid := goos.ValueToUint32(args[2])
|
||||
callback := args[3].(funcWrapper)
|
||||
|
||||
_, _, _ = path, uid, gid // TODO
|
||||
@@ -600,7 +600,7 @@ func (jsfsTruncate) invoke(ctx context.Context, mod api.Module, args ...interfac
|
||||
type jsfsFtruncate struct{}
|
||||
|
||||
func (jsfsFtruncate) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
fd := toUint32(args[0])
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
length := toInt64(args[1])
|
||||
callback := args[2].(funcWrapper)
|
||||
|
||||
@@ -664,7 +664,7 @@ func (jsfsSymlink) invoke(ctx context.Context, mod api.Module, args ...interface
|
||||
type jsfsFsync struct{}
|
||||
|
||||
func (jsfsFsync) invoke(ctx context.Context, mod api.Module, args ...interface{}) (interface{}, error) {
|
||||
fd := toUint32(args[0])
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
callback := args[1].(funcWrapper)
|
||||
|
||||
_ = fd // TODO
|
||||
|
||||
@@ -251,3 +251,14 @@ func (f *stackFunc) Call(ctx context.Context, mod api.Module, wasmStack []uint64
|
||||
func NewStack(name string, mem api.Memory, sp uint32) *stack {
|
||||
return &stack{goarch.NewStack(name, mem, sp)}
|
||||
}
|
||||
|
||||
var Undefined = struct{ name string }{name: "undefined"}
|
||||
|
||||
func ValueToUint32(arg interface{}) uint32 {
|
||||
if arg == RefValueZero || arg == Undefined {
|
||||
return 0
|
||||
} else if u, ok := arg.(uint32); ok {
|
||||
return u
|
||||
}
|
||||
return uint32(arg.(float64))
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func (s *fetchResult) get(_ context.Context, propertyKey string) interface{} {
|
||||
return h
|
||||
case "body":
|
||||
// return undefined as arrayPromise is more complicated than an array.
|
||||
return undefined
|
||||
return goos.Undefined
|
||||
case "status":
|
||||
return uint32(s.res.StatusCode)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/internal/gojs"
|
||||
@@ -13,12 +12,12 @@ import (
|
||||
"github.com/tetratelabs/wazero/internal/gojs/goarch"
|
||||
"github.com/tetratelabs/wazero/internal/gojs/goos"
|
||||
"github.com/tetratelabs/wazero/internal/logging"
|
||||
"github.com/tetratelabs/wazero/internal/sys"
|
||||
)
|
||||
|
||||
func Config(fnd api.FunctionDefinition) (pSampler logging.ParamSampler, pLoggers []logging.ParamLogger, rLoggers []logging.ResultLogger) {
|
||||
switch fnd.Name() {
|
||||
case custom.NameRuntimeWasmWrite:
|
||||
pLoggers = []logging.ParamLogger{runtimeWasmWriteParamLogger}
|
||||
// Don't log NameRuntimeWasmWrite as it is used in panics
|
||||
case custom.NameSyscallValueCall:
|
||||
pSampler = syscallValueCallParamSampler
|
||||
pLoggers = []logging.ParamLogger{syscallValueCallParamLogger}
|
||||
@@ -28,21 +27,6 @@ func Config(fnd api.FunctionDefinition) (pSampler logging.ParamSampler, pLoggers
|
||||
return
|
||||
}
|
||||
|
||||
func runtimeWasmWriteParamLogger(_ context.Context, mod api.Module, w logging.Writer, params []uint64) {
|
||||
mem := mod.Memory()
|
||||
funcName := custom.NameSyscallValueCall
|
||||
stack := goos.NewStack(funcName, mem, uint32(params[0]))
|
||||
fd := stack.ParamUint32(0)
|
||||
pLen := stack.ParamUint32(2)
|
||||
|
||||
w.WriteString(funcName) //nolint
|
||||
w.WriteString("(fd=") //nolint
|
||||
writeI32(w, fd)
|
||||
w.WriteString(",p_len=") //nolint
|
||||
writeI32(w, pLen)
|
||||
w.WriteByte(')') //nolint
|
||||
}
|
||||
|
||||
func syscallValueCallParamLogger(ctx context.Context, mod api.Module, w logging.Writer, params []uint64) {
|
||||
vRef, m, args := syscallValueCallParams(ctx, mod, params)
|
||||
|
||||
@@ -73,10 +57,20 @@ func syscallValueCallParamLogger(ctx context.Context, mod api.Module, w logging.
|
||||
}
|
||||
|
||||
func syscallValueCallParamSampler(ctx context.Context, mod api.Module, params []uint64) bool {
|
||||
vRef, _, _ := syscallValueCallParams(ctx, mod, params)
|
||||
vRef, m, args := syscallValueCallParams(ctx, mod, params)
|
||||
|
||||
// TODO: add more than just filesystem
|
||||
return vRef == goos.RefJsfs
|
||||
if vRef != goos.RefJsfs {
|
||||
return false
|
||||
}
|
||||
|
||||
// Don't amplify logs with stdio reads or writes
|
||||
switch m {
|
||||
case custom.NameFsWrite, custom.NameFsRead:
|
||||
fd := goos.ValueToUint32(args[0])
|
||||
return fd > sys.FdStderr
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func syscallValueCallParams(ctx context.Context, mod api.Module, params []uint64) (goos.Ref, string, []interface{}) {
|
||||
@@ -168,7 +162,3 @@ var oflagToString = [...]string{
|
||||
"SYNC",
|
||||
"TRUNC",
|
||||
}
|
||||
|
||||
func writeI32(w logging.Writer, v uint32) {
|
||||
w.WriteString(strconv.FormatInt(int64(int32(v)), 10)) //nolint
|
||||
}
|
||||
|
||||
@@ -57,10 +57,7 @@ func (e *event) get(_ context.Context, propertyKey string) interface{} {
|
||||
panic(fmt.Sprintf("TODO: event.%s", propertyKey))
|
||||
}
|
||||
|
||||
var (
|
||||
undefined = struct{ name string }{name: "undefined"}
|
||||
NaN = math.NaN()
|
||||
)
|
||||
var NaN = math.NaN()
|
||||
|
||||
// LoadValue reads up to 8 bytes at the memory offset `addr` to return the
|
||||
// value written by storeValue.
|
||||
@@ -69,7 +66,7 @@ var (
|
||||
func LoadValue(ctx context.Context, ref goos.Ref) interface{} { //nolint
|
||||
switch ref {
|
||||
case 0:
|
||||
return undefined
|
||||
return goos.Undefined
|
||||
case goos.RefValueNaN:
|
||||
return NaN
|
||||
case goos.RefValueZero:
|
||||
@@ -119,7 +116,7 @@ func LoadValue(ctx context.Context, ref goos.Ref) interface{} { //nolint
|
||||
// See https://github.com/golang/go/blob/go1.19/misc/wasm/wasm_exec.js#L135-L183
|
||||
func storeRef(ctx context.Context, v interface{}) goos.Ref { //nolint
|
||||
// allow-list because we control all implementations
|
||||
if v == undefined {
|
||||
if v == goos.Undefined {
|
||||
return goos.RefValueUndefined
|
||||
} else if v == nil {
|
||||
return goos.RefValueNull
|
||||
@@ -271,7 +268,7 @@ func (s *State) close() {
|
||||
}
|
||||
|
||||
func toInt64(arg interface{}) int64 {
|
||||
if arg == goos.RefValueZero || arg == undefined {
|
||||
if arg == goos.RefValueZero || arg == goos.Undefined {
|
||||
return 0
|
||||
} else if u, ok := arg.(int64); ok {
|
||||
return u
|
||||
@@ -280,7 +277,7 @@ func toInt64(arg interface{}) int64 {
|
||||
}
|
||||
|
||||
func toUint64(arg interface{}) uint64 {
|
||||
if arg == goos.RefValueZero || arg == undefined {
|
||||
if arg == goos.RefValueZero || arg == goos.Undefined {
|
||||
return 0
|
||||
} else if u, ok := arg.(uint64); ok {
|
||||
return u
|
||||
@@ -288,15 +285,6 @@ func toUint64(arg interface{}) uint64 {
|
||||
return uint64(arg.(float64))
|
||||
}
|
||||
|
||||
func toUint32(arg interface{}) uint32 {
|
||||
if arg == goos.RefValueZero || arg == undefined {
|
||||
return 0
|
||||
} else if u, ok := arg.(uint32); ok {
|
||||
return u
|
||||
}
|
||||
return uint32(arg.(float64))
|
||||
}
|
||||
|
||||
// valueString returns the string form of JavaScript string, boolean and number types.
|
||||
func valueString(v interface{}) string { //nolint
|
||||
if s, ok := v.(string); ok {
|
||||
|
||||
Reference in New Issue
Block a user