blob: 580190692ac09357622f405f7ccbe1987ef255ff [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_BREAKPOINT_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_BREAKPOINT_H_
#include "lib/fit/function.h"
#include "src/developer/debug/ipc/records.h"
#include "src/developer/debug/zxdb/client/breakpoint_settings.h"
#include "src/developer/debug/zxdb/client/client_object.h"
#include "src/developer/debug/zxdb/client/setting_store.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/weak_ptr.h"
namespace zxdb {
class BreakpointLocation;
class Err;
class Target;
class Thread;
class Breakpoint : public ClientObject {
public:
using SetCallback = fit::callback<void(const Err&)>;
explicit Breakpoint(Session* session);
~Breakpoint() override;
fxl::WeakPtr<Breakpoint> GetWeakPtr();
// All of the settings, including the location, are stored in the BreakpointSettings object. This
// API is designed so all settings changes happen atomically.
//
// The backend can fail to set the breakpoint for a variety of reasons (memory write failure, IPC
// failure, out of hardware breakpoints, etc.). The callback to SetSettings() (if provided)
// will indicate success or failure of this operation. This callback will called with an error if
// the breakpoint is deleted before completion.
//
// If an async failure happens and there is no callback provided,
// BreakpointObserver::OnBreakpointUpdateFailure() will be called. These backend errors can occur
// at any time, not just when setting new settings, because new processes or dynamically loaded
// shared libraries can always be added that this breakpoint could apply to.
virtual BreakpointSettings GetSettings() const = 0;
void SetSettings(const BreakpointSettings& settings) { SetSettings(settings, SetCallback()); }
virtual void SetSettings(const BreakpointSettings& settings, SetCallback cb) = 0;
// Returns true if this is an internal breakpoint. Internal breakpoints are used to implement
// other operations and are never exposed to the user.
virtual bool IsInternal() const = 0;
// Returns the locations associated with this breakpoint. These are the actual addresses set. The
// symbols of these may not match the one in the settings (for example, the line number might be
// different due to optimization for each location).
//
// The returned pointers are owned by the Breakpoint and will be changed if the settings or any
// process or module changes take place. Don't cache.
//
// This function has a non-const variant so callers can enable or disable individual locations
// using the resulting pointers.
virtual std::vector<const BreakpointLocation*> GetLocations() const = 0;
virtual std::vector<BreakpointLocation*> GetLocations() = 0;
// Returns the stats for the breakpoint, e.g. hit_count.
virtual debug_ipc::BreakpointStats GetStats() = 0;
SettingStore& settings() { return settings_; }
static fxl::RefPtr<SettingSchema> GetSchema();
private:
// Implements the SettingStore interface for the Breakpoint (uses composition instead of
// inheritance to keep the Breakpoint API simpler).
class Settings : public SettingStore {
public:
explicit Settings(Breakpoint* bp);
protected:
SettingValue GetStorageValue(const std::string& key) const override;
Err SetStorageValue(const std::string& key, SettingValue value) override;
private:
Breakpoint* bp_; // Object that owns us.
};
friend Settings;
Settings settings_;
fxl::WeakPtrFactory<Breakpoint> weak_factory_;
FXL_DISALLOW_COPY_AND_ASSIGN(Breakpoint);
};
// We want to display the menu of types in various places. This macro expands to that. The "indent"
// string is prepended to every line so the left can be indented as needed for the user.
// clang-format off
#define BREAKPOINT_TYPE_HELP(indent) \
indent "software\n" \
indent " Software execution breakpoint. This is a \"normal\" breakpoint where\n" \
indent " the instruction in memory is replaced with an explicit \"break\"\n" \
indent " instruction.\n" \
"\n" \
indent "execute\n" \
indent " Hardware execution breakpoint. This sets a CPU register to stop\n" \
indent " execution when the address is executed. The advantages are that\n" \
indent " this can be done without modifying memory and that per-thread\n" \
indent " breakpoints are more efficient. The disadvantage is that there\n" \
indent " are a limited number of hardware breakpoints.\n" \
"\n" \
indent "read-write\n" \
indent " Hardware read/write breakpoint. Sets a CPU register to break\n" \
indent " whenever the data at the address is read or written.\n" \
"\n" \
indent "write\n" \
indent " Hardware write breakpoint. Sets a CPU register to break whenever\n" \
indent " the data at the address is written.\n"
// clang-format on
} // namespace zxdb
#endif // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_BREAKPOINT_H_