blob: af6059dba7e3dc3efc8c48b612c4395f92969808 [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 <vector>
#include "garnet/bin/zxdb/client/frame_fingerprint.h"
#include "garnet/bin/zxdb/client/thread_controller.h"
namespace zxdb {
class Frame;
class UntilThreadController;
class FinishThreadController : public ThreadController {
public:
// Tag classes that make the constructor variants more clear at the call
// sites (it's hard to tell whether the argument is being stepped "from" or
// "to").
class FromFrame {};
class ToFrame {};
// Steps out of / "from" the given frame, leaving execution at the next
// instruction in the calling (older) frame.
FinishThreadController(FromFrame, const Frame* frame);
// Steps "to" to the given frame address/fingerprint. Any newer frame
// fingerprints will be ignored (execution will continue). The thread will
// only stop at the address when the current frame matches (or is older than)
// the to_frame_fingerprint.
FinishThreadController(ToFrame, uint64_t to_address,
const FrameFingerprint& to_frame_fingerprint);
~FinishThreadController() 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 "Finish"; }
private:
// Callback for when the thread has loaded its frames. This will compute the
// to_frame_fingerprint_.
void InitWithFrames(const std::vector<Frame*>& frames,
std::function<void(const Err&)> cb);
bool HaveAddressAndFingerprint() const;
// Does final initialization given the to_frame_fingerprint_ is known or we
// know we don't need it.
void InitWithFingerprint(std::function<void(const Err&)> cb);
// The instruction and stack pointer of the frame when the address and
// fingerprint are not known. The SP allows disambiguation for two frames
// at the same address.
uint64_t frame_ip_ = 0;
uint64_t frame_sp_ = 0;
// When set, to_address_ will be nonzero and to_frame_fingerprint_ will be
// is_valid(). See HaveAddressAndFingerprint().
uint64_t to_address_ = 0;
FrameFingerprint to_frame_fingerprint_;
// Will be non-null when stepping out. During initialization or when stepping
// out of the earliest stack frame, this can be null.
std::unique_ptr<UntilThreadController> until_controller_;
};
} // namespace zxdb