| // 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 |