diff --git a/runtime/tests/vm/dart/regress_38182_test.dart b/runtime/tests/vm/dart/regress_38182_test.dart new file mode 100644 index 00000000000..952bee4a5d0 --- /dev/null +++ b/runtime/tests/vm/dart/regress_38182_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// VMOptions=--stacktrace_every=1 --deterministic + +void foo1(par) { + try { + () { + // The parameter `par` has to be captured within a closure, but it doesn't + // matter whether or not it's actually used. + print(par.runtimeType); + }; + // We need to throw, otherwise the crash doesn't happen. We don't need to + // catch it explicitly, however. + throw ''; + } finally { + // We need to trigger a lot of stack overflow checks. Somewhere around + // 20000 seems to work. + int x = 0; + for (int loc1 = 0; loc1 < 20000; loc1++) { + x += loc1; + } + print(x); + } +} + +main() { + try { + // Parameter isn't important. + foo1(null); + } catch (e) { + print('foo1 threw'); + } +} diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc index 42f3cdca06b..38650fdf6f4 100644 --- a/runtime/vm/debugger.cc +++ b/runtime/vm/debugger.cc @@ -1156,7 +1156,8 @@ const Context& ActivationFrame::GetSavedCurrentContext() { } else if (obj.IsContext()) { ctx_ = Context::Cast(obj).raw(); } else { - ASSERT(obj.IsNull()); + ASSERT(obj.IsNull() || obj.raw() == Symbols::OptimizedOut().raw()); + ctx_ = Context::null(); } return ctx_; } @@ -1431,7 +1432,12 @@ RawObject* ActivationFrame::GetRelativeContextVar(intptr_t var_ctx_level, intptr_t ctx_slot, intptr_t frame_ctx_level) { const Context& ctx = GetSavedCurrentContext(); - ASSERT(!ctx.IsNull()); + + // It's possible that ctx was optimized out as no locals were captured by the + // context. See issue #38182. + if (ctx.IsNull()) { + return Symbols::OptimizedOut().raw(); + } intptr_t level_diff = frame_ctx_level - var_ctx_level; if (level_diff == 0) {