blob: 82eacdccb0f62e0d152d0df202c0dc5cf9a94f90 [file] [log] [blame]
// Copyright 2021 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_SHARED_STATUS_H_
#define SRC_DEVELOPER_DEBUG_SHARED_STATUS_H_
#include <iosfwd>
#include <string>
#if defined(__Fuchsia__)
#include <zircon/status.h>
#endif
#include "src/developer/debug/shared/serialization.h"
namespace debug {
class Status;
#if defined(__Fuchsia__)
// If there is an error and no message is given, the ZX_* constant will be queried and used.
// If given, the message will be used for most display purposes instead of the platform value, so
// if the value is important and you use a custom message, it should be manually included.
//
// These are split rather than using default values to avoid creating empty std::strings in the
// common case.
Status ZxStatus(zx_status_t s);
Status ZxStatus(zx_status_t s, std::string msg);
#else
// As with the ZxStatus version above, this will automatically use the strerror() string if no
// message is given.
Status ErrnoStatus(int en);
Status ErrnoStatus(int en, std::string msg);
#endif
// A cross-platform status value. It has three modes:
//
// - OK. This is generated by the default constructor and indicates "no error".
//
// - Platform error: This is generated by one of the above platform-specific helpers. It has a
// platform error value (zx_status_t or errno), and it also looks up the corresponding string
// from the operating system.
//
// - Cross-platform error: This can be one of a specific set of enum values that we need to handle
// specially from a code perspective, or a generic error with just a message. There is no
// platform_error number. There may or may not be a message.
class Status {
public:
enum Type : uint32_t {
kSuccess,
kGenericError, // There is an error message but no specific enum or platform error.
kNotSupported, // The system does not support the requested operation.
kNotFound, // For example, the processes to be attached to didn't exist.
kAlreadyExists, // For example, attaching to a process or job that's already attached.
kNoResources, // Ran out of something (like debug registers).
kPlatformError, // An error from the OS in platform_error().
// Not a valid value, used for bounds checking.
kLast,
};
// No error. For error construction, use one of the helpers above.
Status() = default;
// Constructor for a generic platform-independent error. The string may or may not be empty.
explicit Status(std::string msg);
// Constructor for a platform-independent error. The string is optional.
//
// A type of kSuccess or kPlatformError will assert (use the platform-specific helpers above).
explicit Status(Type t, std::string msg = std::string());
// Code creating error should use the platform-specific helpers above. This is for code that
// needs to create from some known internal values. The tag structure is to discourage direct use
// of this function except when you really need it.
//
// The |pe| value should be 0 unless the type is a PlatformError.
struct InternalValues {};
Status(InternalValues tag, Type t, uint64_t pe, std::string msg);
bool ok() const { return type_ == kSuccess; }
bool has_error() const { return !ok(); }
Type type() const { return type_; }
// Assumes the type == kPlatformError.
int64_t platform_error() const { return platform_error_; }
// The message may or may not be set on error.
const std::string& message() const { return message_; }
bool operator==(const Status& other) const {
return type_ == other.type_ && platform_error_ == other.platform_error_ &&
message_ == other.message_;
}
bool operator!=(const Status& other) const { return !operator==(other); }
void Serialize(Serializer& ser, uint32_t ver) { ser | type_ | platform_error_ | message_; }
private:
Type type_ = kSuccess;
int64_t platform_error_ = 0; // Valid when type_ == kPlatformError.
std::string message_;
};
} // namespace debug
std::ostream& operator<<(std::ostream& out, const debug::Status& status);
#endif // SRC_DEVELOPER_DEBUG_SHARED_STATUS_H_