Chromium Code Reviews| Index: runtime/vm/debugger.cc |
| =================================================================== |
| --- runtime/vm/debugger.cc (revision 19823) |
| +++ runtime/vm/debugger.cc (working copy) |
| @@ -304,7 +304,13 @@ |
| // Calculate the context level at the current token index of the frame. |
| intptr_t ActivationFrame::ContextLevel() { |
| - if (context_level_ < 0) { |
| + if (context_level_ < 0 && !ctx_.IsNull()) { |
| + if (code_.is_optimized()) { |
|
Ivan Posva
2013/03/12 20:36:25
I think we can change this test into an ASSERT(!co
Tom Ball
2013/03/12 20:41:45
You're right, that test is no longer needed with t
|
| + // Set context to null, since this and all subsequent frames are |
| + // invalid. |
| + SetContext(Context::Handle()); |
| + return context_level_; |
| + } |
| context_level_ = 0; |
| intptr_t pc_desc_idx = PcDescIndex(); |
| ASSERT(!pc_desc_.IsNull()); |
| @@ -493,13 +499,13 @@ |
| if (var_info.kind == RawLocalVarDescriptors::kStackVar) { |
| *value = GetLocalVarValue(var_info.index); |
| } else { |
| - // TODO(tball): enable context variables once problem with VariableAt() is |
| - // fixed, where frame_ctx_level is sometimes off by 1 (issues 8593 and 8594) |
| - /* |
| ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); |
| - ASSERT(!ctx_.IsNull()); |
| // The context level at the PC/token index of this activation frame. |
| intptr_t frame_ctx_level = ContextLevel(); |
| + if (ctx_.IsNull()) { |
| + *value = Symbols::New("<unknown>"); |
| + return; |
| + } |
| // The context level of the variable. |
| intptr_t var_ctx_level = var_info.scope_id; |
| intptr_t level_diff = frame_ctx_level - var_ctx_level; |
| @@ -516,8 +522,7 @@ |
| } |
| ASSERT(!ctx.IsNull()); |
| *value = ctx.At(ctx_slot); |
| - } */ |
| - *value = Symbols::New("<unknown>"); |
| + } |
| } |
| } |
| @@ -877,6 +882,7 @@ |
| StackFrameIterator iterator(false); |
| StackFrame* frame = iterator.NextFrame(); |
| bool get_saved_context = false; |
| + bool optimized_frame_found = false; |
| while (frame != NULL) { |
| ASSERT(frame->IsValid()); |
| if (frame->IsDartFrame()) { |
| @@ -885,10 +891,16 @@ |
| frame->fp(), |
| frame->sp(), |
| code); |
| - if (get_saved_context && !activation->code().is_optimized()) { |
| - ctx = activation->GetSavedContext(); |
| + if (optimized_frame_found || code.is_optimized()) { |
| + // Set context to null, to avoid returning bad context variable values. |
| + activation->SetContext(Context::Handle()); |
| + optimized_frame_found = true; |
| + } else { |
| + if (get_saved_context) { |
| + ctx = activation->GetSavedContext(); |
| + } |
| + activation->SetContext(ctx); |
| } |
| - activation->SetContext(ctx); |
| stack_trace->AddActivation(activation); |
| get_saved_context = activation->function().IsClosureFunction(); |
| } else if (frame->IsEntryFrame()) { |