blob: d2dc7286e718e7ee0585f4edfea3e462716aea0d [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/client/step_into_specific_thread_controller.h"
#include <lib/syslog/cpp/macros.h>
#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/client/step_into_thread_controller.h"
#include "src/developer/debug/zxdb/client/step_over_thread_controller.h"
#include "src/developer/debug/zxdb/client/thread.h"
namespace zxdb {
StepIntoSpecificThreadController::StepIntoSpecificThreadController(AddressRange over_range)
: into_address_(over_range.end()),
step_over_(std::make_unique<StepOverThreadController>(AddressRanges(over_range))) {}
StepIntoSpecificThreadController::~StepIntoSpecificThreadController() = default;
void StepIntoSpecificThreadController::InitWithThread(Thread* thread,
fit::callback<void(const Err&)> cb) {
SetThread(thread);
step_over_->InitWithThread(thread, std::move(cb));
}
ThreadController::ContinueOp StepIntoSpecificThreadController::GetContinueOp() {
if (step_over_)
return step_over_->GetContinueOp();
if (step_into_)
return step_into_->GetContinueOp();
FX_NOTREACHED(); // Should not be continuing from this state.
return ContinueOp::Continue();
}
ThreadController::StopOp StepIntoSpecificThreadController::OnThreadStop(
debug_ipc::ExceptionType stop_type,
const std::vector<fxl::WeakPtr<Breakpoint>>& hit_breakpoints) {
if (step_over_) {
if (auto op = step_over_->OnThreadStop(stop_type, hit_breakpoints); op != kStopDone)
return op;
// Step over phase complete.
step_over_.reset();
// Validate our current location before doing the "step into".
TargetPointer ip = thread()->GetStack()[0]->GetAddress();
if (ip != into_address_) {
Log("Stepped outside of our range, skipping 'step into'.");
return kStopDone;
}
Log("Step over complete, now stepping into.");
step_into_ = std::make_unique<StepIntoThreadController>(StepMode::kSourceLine);
step_into_->InitWithThread(thread(), [](const Err&) {});
return kContinue;
}
if (step_into_)
return step_into_->OnThreadStop(stop_type, hit_breakpoints);
FX_NOTREACHED(); // Should have reported "done" if we skipped the step into.
return kStopDone;
}
} // namespace zxdb