blob: 0f741e7e4f14985049fbcd6fcbbadecfb335758f [file] [log] [blame]
// Copyright 2019 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_DEBUG_AGENT_LIMBO_PROVIDER_H_
#define SRC_DEVELOPER_DEBUG_DEBUG_AGENT_LIMBO_PROVIDER_H_
#include <lib/fit/result.h>
#include <map>
#include <vector>
#include "src/developer/debug/debug_agent/exception_handle.h"
#include "src/developer/debug/debug_agent/process_handle.h"
#include "src/developer/debug/debug_agent/thread_handle.h"
#include "src/developer/debug/shared/status.h"
namespace debug_agent {
// In charge of providing access to the ProcessLimbo.
//
// Fuchsia can be configured to keep processes that have excepted in a suspension state, called
// Limbo. This provides the possibility for debuggers to attach to those process way after the
// exception occurred. We call this process Just In Time Debugging (JITD).
class LimboProvider {
public:
struct Record {
std::unique_ptr<ProcessHandle> process;
std::unique_ptr<ThreadHandle> thread;
};
// Used when taking over an exception from limbo. This adds on the exception to the normal process
// and thread handles.
struct RetrievedException : public Record {
std::unique_ptr<ExceptionHandle> exception;
};
// Maps process koids to the corresponding records.
using RecordMap = std::map<zx_koid_t, Record>;
using OnEnterLimboCallback = fit::function<void(const Record&)>;
// Limbo can fail to initialize (eg. failed to connect). There is no point querying an invalid
// limbo provider, so callers should check for validity via Valid() before using it. If the limbo
// is invalid, callers should either attempt to initialize again or create another limbo provider.
LimboProvider() = default;
LimboProvider(LimboProvider&&) = default;
virtual ~LimboProvider() = default;
// Callback to be called whenever new processes enter the connected limbo.
// See |on_enter_limbo_| for more details.
void set_on_enter_limbo(OnEnterLimboCallback cb) { on_enter_limbo_ = std::move(cb); }
// Returns true if this limbo provider is set up properly.
virtual bool Valid() const = 0;
// Returns true if the process with the given koid is in limbo.
virtual bool IsProcessInLimbo(zx_koid_t process_koid) const = 0;
// Read-only access to the processes currently waiting in limbo.
virtual const RecordMap& GetLimboRecords() const = 0;
// Consumes the process in limbo.
virtual fit::result<debug::Status, RetrievedException> RetrieveException(
zx_koid_t process_koid) = 0;
virtual debug::Status ReleaseProcess(zx_koid_t process_koid) = 0;
protected:
// Callback to be triggered whenever a new process enters the the limbo. Provides the list of
// new processes that just entered the limbo on this event. |Limbo()| is up to date at the moment
// of this callback.
OnEnterLimboCallback on_enter_limbo_;
};
} // namespace debug_agent
#endif // SRC_DEVELOPER_DEBUG_DEBUG_AGENT_LIMBO_PROVIDER_H_