Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Unified Diff: runtime/vm/debugger.cc

Issue 2521413002: Revert "Implement rewind: drop one or more frames from the debugger." (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/debugger.cc
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 5c54271bc56aefaeca52be2ef11e299e17a169e9..3cdf810c8d678527f68328de0fa065be6d01b0e1 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -6,8 +6,6 @@
#include "include/dart_api.h"
-#include "platform/address_sanitizer.h"
-
#include "vm/code_generator.h"
#include "vm/code_patcher.h"
#include "vm/compiler.h"
@@ -44,7 +42,6 @@ DEFINE_FLAG(bool,
trace_debugger_stacktrace,
false,
"Trace debugger stacktrace collection");
-DEFINE_FLAG(bool, trace_rewind, false, "Trace frame rewind");
DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages");
DEFINE_FLAG(bool,
steal_breakpoints,
@@ -853,24 +850,6 @@ RawObject* ActivationFrame::GetStackVar(intptr_t slot_index) {
}
-bool ActivationFrame::IsRewindable() const {
- if (deopt_frame_.IsNull()) {
- return true;
- }
- // TODO(turnidge): This is conservative. It looks at all values in
- // the deopt_frame_ even though some of them may correspond to other
- // inlined frames.
- Object& obj = Object::Handle();
- for (int i = 0; i < deopt_frame_.Length(); i++) {
- obj = deopt_frame_.At(i);
- if (obj.raw() == Symbols::OptimizedOut().raw()) {
- return false;
- }
- }
- return true;
-}
-
-
void ActivationFrame::PrintContextMismatchError(intptr_t ctx_slot,
intptr_t frame_ctx_level,
intptr_t var_ctx_level) {
@@ -1129,13 +1108,9 @@ void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, bool full) {
}
}
-static bool IsFunctionVisible(const Function& function) {
- return FLAG_show_invisible_frames || function.is_visible();
-}
-
void DebuggerStackTrace::AddActivation(ActivationFrame* frame) {
- if (IsFunctionVisible(frame->function())) {
+ if (FLAG_show_invisible_frames || frame->function().is_visible()) {
trace_.Add(frame);
}
}
@@ -1262,8 +1237,6 @@ Debugger::Debugger()
breakpoint_locations_(NULL),
code_breakpoints_(NULL),
resume_action_(kContinue),
- resume_frame_index_(-1),
- post_deopt_frame_index_(-1),
ignore_breakpoints_(false),
pause_event_(NULL),
obj_cache_(NULL),
@@ -1327,13 +1300,10 @@ static RawFunction* ResolveLibraryFunction(const Library& library,
}
-bool Debugger::SetupStepOverAsyncSuspension(const char** error) {
+bool Debugger::SetupStepOverAsyncSuspension() {
ActivationFrame* top_frame = TopDartFrame();
if (!IsAtAsyncJump(top_frame)) {
// Not at an async operation.
- if (error) {
- *error = "Isolate must be paused at an async suspension point";
- }
return false;
}
Object& closure = Object::Handle(top_frame->GetAsyncOperation());
@@ -1343,42 +1313,24 @@ bool Debugger::SetupStepOverAsyncSuspension(const char** error) {
Breakpoint* bpt = SetBreakpointAtActivation(Instance::Cast(closure), true);
if (bpt == NULL) {
// Unable to set the breakpoint.
- if (error) {
- *error = "Unable to set breakpoint at async suspension point";
- }
return false;
}
return true;
}
-bool Debugger::SetResumeAction(ResumeAction action,
- intptr_t frame_index,
- const char** error) {
- if (error) {
- *error = NULL;
- }
- resume_frame_index_ = -1;
- switch (action) {
- case kStepInto:
- case kStepOver:
- case kStepOut:
- case kContinue:
- resume_action_ = action;
- return true;
- case kStepRewind:
- if (!CanRewindFrame(frame_index, error)) {
- return false;
- }
- resume_action_ = kStepRewind;
- resume_frame_index_ = frame_index;
- return true;
- case kStepOverAsyncSuspension:
- return SetupStepOverAsyncSuspension(error);
- default:
- UNREACHABLE();
- return false;
- }
+void Debugger::SetSingleStep() {
+ resume_action_ = kSingleStep;
+}
+
+
+void Debugger::SetStepOver() {
+ resume_action_ = kStepOver;
+}
+
+
+void Debugger::SetStepOut() {
+ resume_action_ = kStepOut;
}
@@ -1670,7 +1622,6 @@ void Debugger::PauseException(const Instance& exc) {
ASSERT(stack_trace_ == NULL);
stack_trace_ = stack_trace;
Pause(&event);
- HandleSteppingRequest(stack_trace_); // we may get a rewind request
stack_trace_ = NULL;
}
@@ -2596,7 +2547,7 @@ void Debugger::EnterSingleStepMode() {
void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace,
bool skip_next_step) {
stepping_fp_ = 0;
- if (resume_action_ == kStepInto) {
+ if (resume_action_ == kSingleStep) {
// When single stepping, we need to deoptimize because we might be
// stepping into optimized code. This happens in particular if
// the isolate has been interrupted, but can happen in other cases
@@ -2606,7 +2557,7 @@ void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace,
isolate_->set_single_step(true);
skip_next_step_ = skip_next_step;
if (FLAG_verbose_debug) {
- OS::Print("HandleSteppingRequest- kStepInto\n");
+ OS::Print("HandleSteppingRequest- kSingleStep\n");
}
} else if (resume_action_ == kStepOver) {
DeoptimizeWorld();
@@ -2631,244 +2582,6 @@ void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace,
if (FLAG_verbose_debug) {
OS::Print("HandleSteppingRequest- kStepOut %" Px "\n", stepping_fp_);
}
- } else if (resume_action_ == kStepRewind) {
- if (FLAG_trace_rewind) {
- OS::PrintErr("Rewinding to frame %" Pd "\n", resume_frame_index_);
- OS::PrintErr(
- "-------------------------\n"
- "All frames...\n\n");
- StackFrameIterator iterator(false);
- StackFrame* frame = iterator.NextFrame();
- intptr_t num = 0;
- while ((frame != NULL)) {
- OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString());
- frame = iterator.NextFrame();
- }
- }
- RewindToFrame(resume_frame_index_);
- UNREACHABLE();
- }
-}
-
-
-static intptr_t FindNextRewindFrameIndex(DebuggerStackTrace* stack,
- intptr_t frame_index) {
- for (intptr_t i = frame_index + 1; i < stack->Length(); i++) {
- ActivationFrame* frame = stack->FrameAt(i);
- if (frame->IsRewindable()) {
- return i;
- }
- }
- return -1;
-}
-
-
-// Can the top frame be rewound?
-bool Debugger::CanRewindFrame(intptr_t frame_index, const char** error) const {
- // check rewind pc is found
- DebuggerStackTrace* stack = Isolate::Current()->debugger()->StackTrace();
- intptr_t num_frames = stack->Length();
- if (frame_index < 1 || frame_index >= num_frames) {
- if (error) {
- *error = Thread::Current()->zone()->PrintToString(
- "Frame must be in bounds [1..%" Pd
- "]: "
- "saw %" Pd "",
- num_frames - 1, frame_index);
- }
- return false;
- }
- ActivationFrame* frame = stack->FrameAt(frame_index);
- if (!frame->IsRewindable()) {
- intptr_t next_index = FindNextRewindFrameIndex(stack, frame_index);
- if (next_index > 0) {
- *error = Thread::Current()->zone()->PrintToString(
- "Cannot rewind to frame %" Pd
- " due to conflicting compiler "
- "optimizations. "
- "Run the vm with --no-prune-dead-locals to disallow these "
- "optimizations. "
- "Next valid rewind frame is %" Pd ".",
- frame_index, next_index);
- } else {
- *error = Thread::Current()->zone()->PrintToString(
- "Cannot rewind to frame %" Pd
- " due to conflicting compiler "
- "optimizations. "
- "Run the vm with --no-prune-dead-locals to disallow these "
- "optimizations.",
- frame_index);
- }
- return false;
- }
- return true;
-}
-
-
-// Given a return address pc, find the "rewind" pc, which is the pc
-// before the corresponding call.
-static uword LookupRewindPc(const Code& code, uword pc) {
- ASSERT(!code.is_optimized());
- ASSERT(code.ContainsInstructionAt(pc));
-
- uword pc_offset = pc - code.PayloadStart();
- const PcDescriptors& descriptors =
- PcDescriptors::Handle(code.pc_descriptors());
- PcDescriptors::Iterator iter(
- descriptors, RawPcDescriptors::kRewind | RawPcDescriptors::kIcCall |
- RawPcDescriptors::kUnoptStaticCall);
- intptr_t rewind_deopt_id = -1;
- uword rewind_pc = 0;
- while (iter.MoveNext()) {
- if (iter.Kind() == RawPcDescriptors::kRewind) {
- // Remember the last rewind so we don't need to iterator twice.
- rewind_pc = code.PayloadStart() + iter.PcOffset();
- rewind_deopt_id = iter.DeoptId();
- }
- if ((pc_offset == iter.PcOffset()) && (iter.DeoptId() == rewind_deopt_id)) {
- return rewind_pc;
- }
- }
- return 0;
-}
-
-
-void Debugger::RewindToFrame(intptr_t frame_index) {
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- Code& code = Code::Handle(zone);
- Function& function = Function::Handle(zone);
-
- // Find the requested frame.
- StackFrameIterator iterator(false);
- intptr_t current_frame = 0;
- for (StackFrame* frame = iterator.NextFrame(); frame != NULL;
- frame = iterator.NextFrame()) {
- ASSERT(frame->IsValid());
- if (frame->IsDartFrame()) {
- code = frame->LookupDartCode();
- function = code.function();
- if (!IsFunctionVisible(function)) {
- continue;
- }
- if (code.is_optimized()) {
- intptr_t sub_index = 0;
- for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done();
- it.Advance()) {
- if (current_frame == frame_index) {
- RewindToOptimizedFrame(frame, code, sub_index);
- UNREACHABLE();
- }
- current_frame++;
- sub_index++;
- }
- } else {
- if (current_frame == frame_index) {
- // We are rewinding to an unoptimized frame.
- RewindToUnoptimizedFrame(frame, code);
- UNREACHABLE();
- }
- current_frame++;
- }
- }
- }
- UNIMPLEMENTED();
-}
-
-
-void Debugger::RewindToUnoptimizedFrame(StackFrame* frame, const Code& code) {
- // We will be jumping out of the debugger rather than exiting this
- // function, so prepare the debugger state.
- stack_trace_ = NULL;
- resume_action_ = kContinue;
- resume_frame_index_ = -1;
- EnterSingleStepMode();
-
- uword rewind_pc = LookupRewindPc(code, frame->pc());
- if (FLAG_trace_rewind && rewind_pc == 0) {
- OS::PrintErr("Unable to find rewind pc for pc(%" Px ")\n", frame->pc());
- }
- ASSERT(rewind_pc != 0);
- if (FLAG_trace_rewind) {
- OS::PrintErr(
- "===============================\n"
- "Rewinding to unoptimized frame:\n"
- " rewind_pc(0x%" Px ") sp(0x%" Px ") fp(0x%" Px
- ")\n"
- "===============================\n",
- rewind_pc, frame->sp(), frame->fp());
- }
- Exceptions::JumpToFrame(Thread::Current(), rewind_pc, frame->sp(),
- frame->fp(), true /* clear lazy deopt at target */);
- UNREACHABLE();
-}
-
-
-void Debugger::RewindToOptimizedFrame(StackFrame* frame,
- const Code& optimized_code,
- intptr_t sub_index) {
- post_deopt_frame_index_ = sub_index;
-
- // We will be jumping out of the debugger rather than exiting this
- // function, so prepare the debugger state.
- stack_trace_ = NULL;
- resume_action_ = kContinue;
- resume_frame_index_ = -1;
- EnterSingleStepMode();
-
- if (FLAG_trace_rewind) {
- OS::PrintErr(
- "===============================\n"
- "Deoptimizing frame for rewind:\n"
- " deopt_pc(0x%" Px ") sp(0x%" Px ") fp(0x%" Px
- ")\n"
- "===============================\n",
- frame->pc(), frame->sp(), frame->fp());
- }
- Thread* thread = Thread::Current();
- thread->set_resume_pc(frame->pc());
- uword deopt_stub_pc = StubCode::DeoptForRewind_entry()->EntryPoint();
- Exceptions::JumpToFrame(thread, deopt_stub_pc, frame->sp(), frame->fp(),
- true /* clear lazy deopt at target */);
- UNREACHABLE();
-}
-
-
-void Debugger::RewindPostDeopt() {
- intptr_t rewind_frame = post_deopt_frame_index_;
- post_deopt_frame_index_ = -1;
- if (FLAG_trace_rewind) {
- OS::PrintErr("Post deopt, jumping to frame %" Pd "\n", rewind_frame);
- OS::PrintErr(
- "-------------------------\n"
- "All frames...\n\n");
- StackFrameIterator iterator(false);
- StackFrame* frame = iterator.NextFrame();
- intptr_t num = 0;
- while ((frame != NULL)) {
- OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString());
- frame = iterator.NextFrame();
- }
- }
-
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- Code& code = Code::Handle(zone);
-
- StackFrameIterator iterator(false);
- intptr_t current_frame = 0;
- for (StackFrame* frame = iterator.NextFrame(); frame != NULL;
- frame = iterator.NextFrame()) {
- ASSERT(frame->IsValid());
- if (frame->IsDartFrame()) {
- code = frame->LookupDartCode();
- ASSERT(!code.is_optimized());
- if (current_frame == rewind_frame) {
- RewindToUnoptimizedFrame(frame, code);
- UNREACHABLE();
- }
- current_frame++;
- }
}
}
@@ -3080,7 +2793,7 @@ RawError* Debugger::PauseBreakpoint() {
// We are at the entry of an async function.
// We issue a step over to resume at the point after the await statement.
- SetResumeAction(kStepOver);
+ SetStepOver();
// When we single step from a user breakpoint, our next stepping
// point will be at the exact same pc. Skip it.
HandleSteppingRequest(stack_trace_, true /* skip next step */);
@@ -3133,7 +2846,7 @@ void Debugger::PauseDeveloper(const String& msg) {
// We are in the native call to Developer_debugger. the developer
// gets a better experience by not seeing this call. To accomplish
// this, we continue execution until the call exits (step out).
- SetResumeAction(kStepOut);
+ SetStepOut();
HandleSteppingRequest(stack_trace_);
stack_trace_ = NULL;
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698