From 5f7467b3e00a01153ac2d51d5efd3fcfb25c4bc3 Mon Sep 17 00:00:00 2001 From: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com> Date: Thu, 15 Dec 2022 14:03:20 +0900 Subject: [PATCH] Enables debug info (a.k.a. DWARF) by default (#924) This makes DWARF enabled by default, with an opt-out flag. This didn't need to be experimental as the feature was requested for a long time and there's no API impact to using it. Signed-off-by: Adrian Cole --- cmd/wazero/wazero.go | 3 +- cmd/wazero/wazero_test.go | 5 --- config.go | 44 +++++++++++++++++++ config_test.go | 9 ++++ experimental/dwarf_test.go => dwarf_test.go | 16 +++---- experimental/dwarf.go | 47 --------------------- runtime.go | 5 ++- 7 files changed, 64 insertions(+), 65 deletions(-) rename experimental/dwarf_test.go => dwarf_test.go (90%) delete mode 100644 experimental/dwarf.go diff --git a/cmd/wazero/wazero.go b/cmd/wazero/wazero.go index 5923da26..a7ba882f 100644 --- a/cmd/wazero/wazero.go +++ b/cmd/wazero/wazero.go @@ -12,12 +12,11 @@ import ( "strings" "github.com/tetratelabs/wazero" - "github.com/tetratelabs/wazero/experimental" "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" "github.com/tetratelabs/wazero/sys" ) -var ctx = experimental.WithDWARFBasedStackTrace(context.Background()) +var ctx = context.Background() func main() { doMain(os.Stdout, os.Stderr, os.Exit) diff --git a/cmd/wazero/wazero_test.go b/cmd/wazero/wazero_test.go index bf43ee99..b301f1eb 100644 --- a/cmd/wazero/wazero_test.go +++ b/cmd/wazero/wazero_test.go @@ -9,7 +9,6 @@ import ( "path/filepath" "testing" - "github.com/tetratelabs/wazero/experimental" "github.com/tetratelabs/wazero/internal/testing/require" ) @@ -158,7 +157,3 @@ func runMain(t *testing.T, args []string) (int, string, string) { return exitCode, stdOut.String(), stdErr.String() } - -func TestContext(t *testing.T) { - require.True(t, experimental.DWARFBasedStackTraceEnabled(ctx)) -} diff --git a/config.go b/config.go index 5066e66b..788372ac 100644 --- a/config.go +++ b/config.go @@ -66,6 +66,41 @@ type RuntimeConfig interface { // // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#grow-mem WithMemoryCapacityFromMax(memoryCapacityFromMax bool) RuntimeConfig + + // WithDebugInfoEnabled toggles DWARF based stack traces in the face of + // runtime errors. Defaults to true. + // + // Those who wish to disable this, can like so: + // + // r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfig().WithDebugInfoEnabled(false) + // + // When disabled, a stack trace message looks like: + // + // wasm stack trace: + // .runtime._panic(i32) + // .myFunc() + // .main.main() + // .runtime.run() + // ._start() + // + // When enabled, the stack trace includes source code information: + // + // wasm stack trace: + // .runtime._panic(i32) + // 0x16e2: /opt/homebrew/Cellar/tinygo/0.26.0/src/runtime/runtime_tinygowasm.go:73:6 + // .myFunc() + // 0x190b: /Users/XXXXX/wazero/internal/testing/dwarftestdata/testdata/main.go:19:7 + // .main.main() + // 0x18ed: /Users/XXXXX/wazero/internal/testing/dwarftestdata/testdata/main.go:4:3 + // .runtime.run() + // 0x18cc: /opt/homebrew/Cellar/tinygo/0.26.0/src/runtime/scheduler_none.go:26:10 + // ._start() + // 0x18b6: /opt/homebrew/Cellar/tinygo/0.26.0/src/runtime/runtime_wasm_wasi.go:22:5 + // + // Note: This only takes into effect when the original Wasm binary has the + // DWARF "custom sections" that are often stripped, depending on + // optimization flags passed to the compiler. + WithDebugInfoEnabled(bool) RuntimeConfig } // NewRuntimeConfig returns a RuntimeConfig using the compiler if it is supported in this environment, @@ -79,6 +114,7 @@ type runtimeConfig struct { memoryLimitPages uint32 memoryCapacityFromMax bool isInterpreter bool + dwarfDisabled bool // negative as defaults to enabled newEngine func(context.Context, api.CoreFeatures) wasm.Engine } @@ -87,6 +123,7 @@ var engineLessConfig = &runtimeConfig{ enabledFeatures: api.CoreFeaturesV2, memoryLimitPages: wasm.MemoryLimitPages, memoryCapacityFromMax: false, + dwarfDisabled: false, } // NewRuntimeConfigCompiler compiles WebAssembly modules into @@ -148,6 +185,13 @@ func (c *runtimeConfig) WithMemoryCapacityFromMax(memoryCapacityFromMax bool) Ru return ret } +// WithDebugInfoEnabled implements RuntimeConfig.WithDebugInfoEnabled +func (c *runtimeConfig) WithDebugInfoEnabled(dwarfEnabled bool) RuntimeConfig { + ret := c.clone() + ret.dwarfDisabled = !dwarfEnabled + return ret +} + // CompiledModule is a WebAssembly module ready to be instantiated (Runtime.InstantiateModule) as an api.Module. // // In WebAssembly terminology, this is a decoded, validated, and possibly also compiled module. wazero avoids using diff --git a/config_test.go b/config_test.go index dfdd59c5..dbf6d17a 100644 --- a/config_test.go +++ b/config_test.go @@ -50,6 +50,15 @@ func TestRuntimeConfig(t *testing.T) { memoryCapacityFromMax: true, }, }, + { + name: "WithDebugInfoEnabled", + with: func(c RuntimeConfig) RuntimeConfig { + return c.WithDebugInfoEnabled(false) + }, + expected: &runtimeConfig{ + dwarfDisabled: true, // dwarf is a more technical name and ok here. + }, + }, } for _, tt := range tests { diff --git a/experimental/dwarf_test.go b/dwarf_test.go similarity index 90% rename from experimental/dwarf_test.go rename to dwarf_test.go index aae8aa51..80c8f5ff 100644 --- a/experimental/dwarf_test.go +++ b/dwarf_test.go @@ -1,4 +1,4 @@ -package experimental_test +package wazero_test import ( "bufio" @@ -8,25 +8,24 @@ import ( "testing" "github.com/tetratelabs/wazero" - "github.com/tetratelabs/wazero/experimental" "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" "github.com/tetratelabs/wazero/internal/platform" "github.com/tetratelabs/wazero/internal/testing/dwarftestdata" "github.com/tetratelabs/wazero/internal/testing/require" ) -func TestWithDWARFBasedStackTrace(t *testing.T) { +func TestWithDebugInfo(t *testing.T) { ctx := context.Background() - require.False(t, experimental.DWARFBasedStackTraceEnabled(ctx)) - ctx = experimental.WithDWARFBasedStackTrace(ctx) - require.True(t, experimental.DWARFBasedStackTraceEnabled(ctx)) type testCase struct { name string r wazero.Runtime } - tests := []testCase{{name: "interpreter", r: wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())}} + tests := []testCase{{ + name: "interpreter", + r: wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter()), + }} if platform.CompilerSupported() { tests = append(tests, testCase{ @@ -167,8 +166,7 @@ wasm stack trace: compiled, err := r.CompileModule(ctx, lang.bin) require.NoError(t, err) - // Use context.Background to ensure that DWARF is a compile-time option. - _, err = r.InstantiateModule(context.Background(), compiled, wazero.NewModuleConfig()) + _, err = r.InstantiateModule(ctx, compiled, wazero.NewModuleConfig()) require.Error(t, err) errStr := err.Error() diff --git a/experimental/dwarf.go b/experimental/dwarf.go deleted file mode 100644 index 4409b217..00000000 --- a/experimental/dwarf.go +++ /dev/null @@ -1,47 +0,0 @@ -package experimental - -import ( - "context" -) - -type enableDWARFBasedStackTraceKey struct{} - -// WithDWARFBasedStackTrace enables the DWARF based stack traces in the face of runtime errors. -// This only takes into effect when the original Wasm binary has the DWARF "custom sections" -// that are often stripped depending on the optimization options of the compilers. -// -// For example, when this is not enabled, the stack trace message looks like: -// -// wasm stack trace: -// .runtime._panic(i32) -// .myFunc() -// .main.main() -// .runtime.run() -// ._start() -// -// and when it is enabled: -// -// wasm stack trace: -// .runtime._panic(i32) -// 0x16e2: /opt/homebrew/Cellar/tinygo/0.26.0/src/runtime/runtime_tinygowasm.go:73:6 -// .myFunc() -// 0x190b: /Users/XXXXX/wazero/internal/testing/dwarftestdata/testdata/main.go:19:7 -// .main.main() -// 0x18ed: /Users/XXXXX/wazero/internal/testing/dwarftestdata/testdata/main.go:4:3 -// .runtime.run() -// 0x18cc: /opt/homebrew/Cellar/tinygo/0.26.0/src/runtime/scheduler_none.go:26:10 -// ._start() -// 0x18b6: /opt/homebrew/Cellar/tinygo/0.26.0/src/runtime/runtime_wasm_wasi.go:22:5 -// -// which contains the source code information. -// -// See https://github.com/tetratelabs/wazero/pull/881 for more context. -func WithDWARFBasedStackTrace(ctx context.Context) context.Context { - return context.WithValue(ctx, enableDWARFBasedStackTraceKey{}, struct{}{}) -} - -// DWARFBasedStackTraceEnabled returns true if the given context has the option enabling the DWARF -// based stack trace, and false otherwise. -func DWARFBasedStackTraceEnabled(ctx context.Context) bool { - return ctx.Value(enableDWARFBasedStackTraceKey{}) != nil -} diff --git a/runtime.go b/runtime.go index 4c217663..3270533f 100644 --- a/runtime.go +++ b/runtime.go @@ -138,6 +138,7 @@ func NewRuntimeWithConfig(ctx context.Context, rConfig RuntimeConfig) Runtime { memoryLimitPages: config.memoryLimitPages, memoryCapacityFromMax: config.memoryCapacityFromMax, isInterpreter: config.isInterpreter, + dwarfDisabled: config.dwarfDisabled, } } @@ -149,6 +150,7 @@ type runtime struct { memoryLimitPages uint32 memoryCapacityFromMax bool isInterpreter bool + dwarfDisabled bool compiledModules []*compiledModule } @@ -172,9 +174,8 @@ func (r *runtime) CompileModule(ctx context.Context, binary []byte) (CompiledMod return nil, errors.New("invalid binary") } - dwarfEnabled := experimentalapi.DWARFBasedStackTraceEnabled(ctx) internal, err := binaryformat.DecodeModule(binary, r.enabledFeatures, - r.memoryLimitPages, r.memoryCapacityFromMax, dwarfEnabled, false) + r.memoryLimitPages, r.memoryCapacityFromMax, !r.dwarfDisabled, false) if err != nil { return nil, err } else if err = internal.Validate(r.enabledFeatures); err != nil {