blob: 45fa5195a25d56492f3d088e820f599e71e90417 [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.
#ifndef SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_MOCK_FRAME_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_MOCK_FRAME_H_
#include "src/developer/debug/ipc/records.h"
#include "src/developer/debug/shared/register_id.h"
#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/symbols/arch.h"
#include "src/developer/debug/zxdb/symbols/location.h"
#include "src/lib/fxl/memory/ref_ptr.h"
namespace zxdb {
class EvalContextImpl;
class MockSymbolDataProvider;
// Provides a MockFrame implementation that just returns constant values for everything. Tests can
// override this to implement the subset of functionality they need.
class MockFrame : public Frame {
public:
// Session and Thread can be null as long as no code that uses this object needs it.
//
// The physical frame is the non-inlined call frame associated with this one. The pointer must
// outlive this class (normally both are owned by the Stack). A null physical frame indicates that
// this is not inline.
MockFrame(Session* session, Thread* thread, const Location& location, uint64_t sp,
uint64_t cfa = 0, std::vector<debug::RegisterValue> regs = {}, uint64_t frame_base = 0,
const Frame* physical_frame = nullptr, bool is_ambiguous_inline = false);
// This variant makes a location with a mock function object of the given name and the default
// value of everything else. It's usuaully enough for many types of tests.
MockFrame(Session* session, Thread* thread, TargetPointer ip, TargetPointer sp,
const std::string& func_name, FileLine file_line);
~MockFrame() override;
// Use GetLocation() to retrieve the location.
void set_location(Location l) { location_ = std::move(l); }
// Overrides all IPs with a new address, but doesn't change anything else about the location
// including the stack or symbols.
void SetAddress(uint64_t address);
// Overrides the location's file_line with the new value, leaving everything else as-is.
void SetFileLine(const FileLine& file_line);
void set_is_ambiguous_inline(bool ambiguous) { is_ambiguous_inline_ = ambiguous; }
MockSymbolDataProvider* GetMockSymbolDataProvider();
// Frame implementation.
Thread* GetThread() const override;
bool IsInline() const override;
const Frame* GetPhysicalFrame() const override;
const Location& GetLocation() const override;
uint64_t GetAddress() const override;
const std::vector<debug::RegisterValue>* GetRegisterCategorySync(
debug::RegisterCategory category) const override;
void GetRegisterCategoryAsync(
debug::RegisterCategory category, bool always_request,
fit::function<void(const Err&, const std::vector<debug::RegisterValue>&)> cb) override;
void WriteRegister(debug::RegisterID id, std::vector<uint8_t> data,
fit::callback<void(const Err&)> cb) override;
std::optional<uint64_t> GetBasePointer() const override;
void GetBasePointerAsync(fit::callback<void(uint64_t bp)> cb) override;
uint64_t GetStackPointer() const override;
uint64_t GetCanonicalFrameAddress() const override;
fxl::RefPtr<SymbolDataProvider> GetSymbolDataProvider() const override;
fxl::RefPtr<EvalContext> GetEvalContext() const override;
bool IsAmbiguousInlineLocation() const override;
private:
Thread* thread_;
uint64_t sp_;
uint64_t cfa_;
std::vector<debug::RegisterValue> general_registers_;
uint64_t frame_base_;
const Frame* physical_frame_; // Null if non-inlined.
Location location_;
mutable fxl::RefPtr<MockSymbolDataProvider> symbol_data_provider_; // Lazy.
mutable fxl::RefPtr<EvalContextImpl> eval_context_; // Lazy.
bool is_ambiguous_inline_ = false;
FXL_DISALLOW_COPY_AND_ASSIGN(MockFrame);
};
} // namespace zxdb
#endif // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_MOCK_FRAME_H_