blob: d99c3a3f14f5aef95265d8459730a3fdc6de4bd4 [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.
#pragma once
#include <memory>
#include "garnet/bin/zxdb/client/frame_fingerprint.h"
#include "garnet/bin/zxdb/client/step_mode.h"
#include "garnet/bin/zxdb/client/thread_controller.h"
#include "garnet/bin/zxdb/common/address_range.h"
namespace zxdb {
class FinishThreadController;
class StepThreadController;
// This controller causes the thread to single-step as long as the CPU is in
// a given address range or any stack frame called from it. Contrast with
// the StepThreadController which does not do the sub-frames.
//
// This class works by:
// 1. Single-stepping in the range.
// 2. When the range is exited, see if the address is in a sub-frame.
// 3. Step out of the sub-frame if so, exit if not.
// 4. Repeat.
class StepOverThreadController : public ThreadController {
public:
// Constructor for kSourceLine and kInstruction modes. It will initialize
// itself to the thread's current position when the thread is attached.
explicit StepOverThreadController(StepMode mode);
// Constructor for a kAddressRange mode (the mode is implicit). Continues
// execution as long as the IP is in range.
explicit StepOverThreadController(AddressRange range);
~StepOverThreadController() override;
// ThreadController implementation.
void InitWithThread(Thread* thread,
std::function<void(const Err&)> cb) override;
ContinueOp GetContinueOp() override;
StopOp OnThreadStop(
debug_ipc::NotifyException::Type stop_type,
const std::vector<fxl::WeakPtr<Breakpoint>>& hit_breakpoints) override;
const char* GetName() const override { return "Step Over"; }
private:
// The fingerprint of the frame we're stepping in. Anything newer than this
// is a child frame we should step through, and anything older than this
// means we exited the function and should stop stepping.
FrameFingerprint frame_fingerprint_;
// Always non-null, manages stepping in the original function.
std::unique_ptr<StepThreadController> step_into_;
// Only set when we're stepping out to get back to the original function.
std::unique_ptr<FinishThreadController> finish_;
};
} // namespace zxdb