|
@@ -2,9 +2,15 @@
|
|
|
// Licensed under GPLv2 or any later version
|
|
// Licensed under GPLv2 or any later version
|
|
|
// Refer to the license.txt file included.
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
|
|
+#include <array>
|
|
|
|
|
+#include <chrono>
|
|
|
|
|
+#include <iomanip>
|
|
|
|
|
+#include <sstream>
|
|
|
|
|
+
|
|
|
#include "common/bit_field.h"
|
|
#include "common/bit_field.h"
|
|
|
#include "common/common_types.h"
|
|
#include "common/common_types.h"
|
|
|
#include "common/logging/log.h"
|
|
#include "common/logging/log.h"
|
|
|
|
|
+#include "core/hle/result.h"
|
|
|
#include "core/hle/service/err_f.h"
|
|
#include "core/hle/service/err_f.h"
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
@@ -12,12 +18,45 @@
|
|
|
|
|
|
|
|
namespace ERR_F {
|
|
namespace ERR_F {
|
|
|
|
|
|
|
|
-enum {
|
|
|
|
|
- ErrSpecifier0 = 0,
|
|
|
|
|
- ErrSpecifier1 = 1,
|
|
|
|
|
- ErrSpecifier3 = 3,
|
|
|
|
|
- ErrSpecifier4 = 4,
|
|
|
|
|
|
|
+enum class FatalErrType : u32 {
|
|
|
|
|
+ Generic = 0,
|
|
|
|
|
+ Corrupted = 1,
|
|
|
|
|
+ CardRemoved = 2,
|
|
|
|
|
+ Exception = 3,
|
|
|
|
|
+ ResultFailure = 4,
|
|
|
|
|
+ Logged = 5,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+enum class ExceptionType : u32 {
|
|
|
|
|
+ PrefetchAbort = 0,
|
|
|
|
|
+ DataAbort = 1,
|
|
|
|
|
+ Undefined = 2,
|
|
|
|
|
+ VectorFP = 3,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+struct ExceptionInfo {
|
|
|
|
|
+ u8 exception_type;
|
|
|
|
|
+ INSERT_PADDING_BYTES(3);
|
|
|
|
|
+ u32 sr;
|
|
|
|
|
+ u32 ar;
|
|
|
|
|
+ u32 fpexc;
|
|
|
|
|
+ u32 fpinst;
|
|
|
|
|
+ u32 fpinst2;
|
|
|
|
|
+};
|
|
|
|
|
+static_assert(sizeof(ExceptionInfo) == 0x18, "ExceptionInfo struct has incorrect size");
|
|
|
|
|
+
|
|
|
|
|
+struct ExceptionContext final {
|
|
|
|
|
+ std::array<u32, 16> arm_regs;
|
|
|
|
|
+ u32 cpsr;
|
|
|
};
|
|
};
|
|
|
|
|
+static_assert(sizeof(ExceptionContext) == 0x44, "ExceptionContext struct has incorrect size");
|
|
|
|
|
+
|
|
|
|
|
+struct ExceptionData {
|
|
|
|
|
+ ExceptionInfo exception_info;
|
|
|
|
|
+ ExceptionContext exception_context;
|
|
|
|
|
+ INSERT_PADDING_WORDS(1);
|
|
|
|
|
+};
|
|
|
|
|
+static_assert(sizeof(ExceptionData) == 0x60, "ExceptionData struct has incorrect size");
|
|
|
|
|
|
|
|
// This is used instead of ResultCode from result.h
|
|
// This is used instead of ResultCode from result.h
|
|
|
// because we can't have non-trivial data members in unions.
|
|
// because we can't have non-trivial data members in unions.
|
|
@@ -30,150 +69,191 @@ union RSL {
|
|
|
BitField<27, 5, u32> level;
|
|
BitField<27, 5, u32> level;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-union ErrInfo {
|
|
|
|
|
- u8 specifier;
|
|
|
|
|
-
|
|
|
|
|
- struct {
|
|
|
|
|
- u8 specifier; // 0x0
|
|
|
|
|
- u8 rev_high; // 0x1
|
|
|
|
|
- u16 rev_low; // 0x2
|
|
|
|
|
- RSL result_code; // 0x4
|
|
|
|
|
- u32 address; // 0x8
|
|
|
|
|
- INSERT_PADDING_BYTES(4); // 0xC
|
|
|
|
|
- u32 pid_low; // 0x10
|
|
|
|
|
- u32 pid_high; // 0x14
|
|
|
|
|
- u32 aid_low; // 0x18
|
|
|
|
|
- u32 aid_high; // 0x1C
|
|
|
|
|
- } errtype1;
|
|
|
|
|
-
|
|
|
|
|
- struct {
|
|
|
|
|
- u8 specifier; // 0x0
|
|
|
|
|
- u8 rev_high; // 0x1
|
|
|
|
|
- u16 rev_low; // 0x2
|
|
|
|
|
- INSERT_PADDING_BYTES(0xC); // 0x4
|
|
|
|
|
- u32 pid_low; // 0x10
|
|
|
|
|
- u32 pid_high; // 0x14
|
|
|
|
|
- u32 aid_low; // 0x18
|
|
|
|
|
- u32 aid_high; // 0x1C
|
|
|
|
|
- u8 error_type; // 0x20
|
|
|
|
|
- INSERT_PADDING_BYTES(3); // 0x21
|
|
|
|
|
- u32 fault_status_reg; // 0x24
|
|
|
|
|
- u32 fault_addr; // 0x28
|
|
|
|
|
- u32 fpexc; // 0x2C
|
|
|
|
|
- u32 finst; // 0x30
|
|
|
|
|
- u32 finst2; // 0x34
|
|
|
|
|
- INSERT_PADDING_BYTES(0x34); // 0x38
|
|
|
|
|
- u32 sp; // 0x6C
|
|
|
|
|
- u32 pc; // 0x70
|
|
|
|
|
- u32 lr; // 0x74
|
|
|
|
|
- u32 cpsr; // 0x78
|
|
|
|
|
- } errtype3;
|
|
|
|
|
-
|
|
|
|
|
- struct {
|
|
|
|
|
- u8 specifier; // 0x0
|
|
|
|
|
- u8 rev_high; // 0x1
|
|
|
|
|
- u16 rev_low; // 0x2
|
|
|
|
|
- RSL result_code; // 0x4
|
|
|
|
|
- INSERT_PADDING_BYTES(8); // 0x8
|
|
|
|
|
- u32 pid_low; // 0x10
|
|
|
|
|
- u32 pid_high; // 0x14
|
|
|
|
|
- u32 aid_low; // 0x18
|
|
|
|
|
- u32 aid_high; // 0x1C
|
|
|
|
|
- char debug_string1[0x2E]; // 0x20
|
|
|
|
|
- char debug_string2[0x2E]; // 0x4E
|
|
|
|
|
- } errtype4;
|
|
|
|
|
|
|
+struct ErrInfo {
|
|
|
|
|
+ struct ErrInfoCommon {
|
|
|
|
|
+ u8 specifier; // 0x0
|
|
|
|
|
+ u8 rev_high; // 0x1
|
|
|
|
|
+ u16 rev_low; // 0x2
|
|
|
|
|
+ RSL result_code; // 0x4
|
|
|
|
|
+ u32 pc_address; // 0x8
|
|
|
|
|
+ u32 pid; // 0xC
|
|
|
|
|
+ u32 title_id_low; // 0x10
|
|
|
|
|
+ u32 title_id_high; // 0x14
|
|
|
|
|
+ u32 app_title_id_low; // 0x18
|
|
|
|
|
+ u32 app_title_id_high; // 0x1C
|
|
|
|
|
+ } errinfo_common;
|
|
|
|
|
+ static_assert(sizeof(ErrInfoCommon) == 0x20, "ErrInfoCommon struct has incorrect size");
|
|
|
|
|
+
|
|
|
|
|
+ union {
|
|
|
|
|
+ struct {
|
|
|
|
|
+ char data[0x60]; // 0x20
|
|
|
|
|
+ } generic;
|
|
|
|
|
+
|
|
|
|
|
+ struct {
|
|
|
|
|
+ ExceptionData exception_data; // 0x20
|
|
|
|
|
+ } exception;
|
|
|
|
|
+
|
|
|
|
|
+ struct {
|
|
|
|
|
+ char message[0x60]; // 0x20
|
|
|
|
|
+ } result_failure;
|
|
|
|
|
+ };
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-enum { PrefetchAbort = 0, DataAbort = 1, UndefInstr = 2, VectorFP = 3 };
|
|
|
|
|
|
|
+static std::string GetErrType(u8 type_code) {
|
|
|
|
|
+ switch (static_cast<FatalErrType>(type_code)) {
|
|
|
|
|
+ case FatalErrType::Generic:
|
|
|
|
|
+ return "Generic";
|
|
|
|
|
+ case FatalErrType::Corrupted:
|
|
|
|
|
+ return "Corrupted";
|
|
|
|
|
+ case FatalErrType::CardRemoved:
|
|
|
|
|
+ return "CardRemoved";
|
|
|
|
|
+ case FatalErrType::Exception:
|
|
|
|
|
+ return "Exception";
|
|
|
|
|
+ case FatalErrType::ResultFailure:
|
|
|
|
|
+ return "ResultFailure";
|
|
|
|
|
+ case FatalErrType::Logged:
|
|
|
|
|
+ return "Logged";
|
|
|
|
|
+ default:
|
|
|
|
|
+ return "Unknown Error Type";
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-static std::string GetErrInfo3Type(u8 type_code) {
|
|
|
|
|
- switch (type_code) {
|
|
|
|
|
- case PrefetchAbort:
|
|
|
|
|
|
|
+static std::string GetExceptionType(u8 type_code) {
|
|
|
|
|
+ switch (static_cast<ExceptionType>(type_code)) {
|
|
|
|
|
+ case ExceptionType::PrefetchAbort:
|
|
|
return "Prefetch Abort";
|
|
return "Prefetch Abort";
|
|
|
- case DataAbort:
|
|
|
|
|
|
|
+ case ExceptionType::DataAbort:
|
|
|
return "Data Abort";
|
|
return "Data Abort";
|
|
|
- case UndefInstr:
|
|
|
|
|
- return "Undefined Instruction";
|
|
|
|
|
- case VectorFP:
|
|
|
|
|
- return "Vector Floating Point";
|
|
|
|
|
|
|
+ case ExceptionType::Undefined:
|
|
|
|
|
+ return "Undefined Exception";
|
|
|
|
|
+ case ExceptionType::VectorFP:
|
|
|
|
|
+ return "Vector Floating Point Exception";
|
|
|
default:
|
|
default:
|
|
|
- return "unknown";
|
|
|
|
|
|
|
+ return "Unknown Exception Type";
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static std::string GetCurrentSystemTime() {
|
|
|
|
|
+ auto now = std::chrono::system_clock::now();
|
|
|
|
|
+ auto time = std::chrono::system_clock::to_time_t(now);
|
|
|
|
|
+
|
|
|
|
|
+ std::stringstream time_stream;
|
|
|
|
|
+ time_stream << std::put_time(std::localtime(&time), "%Y/%m/%d %H:%M:%S");
|
|
|
|
|
+ return time_stream.str();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void LogGenericInfo(const ErrInfo::ErrInfoCommon& errinfo_common) {
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "PID: 0x%08X", errinfo_common.pid);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "REV: 0x%08X_0x%08X", errinfo_common.rev_high,
|
|
|
|
|
+ errinfo_common.rev_low);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "TID: 0x%08X_0x%08X", errinfo_common.title_id_high,
|
|
|
|
|
+ errinfo_common.title_id_low);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errinfo_common.app_title_id_high,
|
|
|
|
|
+ errinfo_common.app_title_id_low);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errinfo_common.pc_address);
|
|
|
|
|
+
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errinfo_common.result_code.raw);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, " Level: %u", errinfo_common.result_code.level.Value());
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, " Summary: %u", errinfo_common.result_code.summary.Value());
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, " Module: %u", errinfo_common.result_code.module.Value());
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, " Desc: %u", errinfo_common.result_code.description.Value());
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ThrowFatalError function
|
|
|
|
|
+ * Inputs:
|
|
|
|
|
+ * 0 : Header code [0x00010800]
|
|
|
|
|
+ * 1-32 : FatalErrInfo
|
|
|
|
|
+ * Outputs:
|
|
|
|
|
+ * 0 : Header code
|
|
|
|
|
+ * 1 : Result code
|
|
|
|
|
+ */
|
|
|
static void ThrowFatalError(Service::Interface* self) {
|
|
static void ThrowFatalError(Service::Interface* self) {
|
|
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
|
u32* cmd_buff = Kernel::GetCommandBuffer();
|
|
|
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "Fatal error!");
|
|
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "Fatal error");
|
|
|
const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]);
|
|
const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "Fatal error type: %s",
|
|
|
|
|
+ GetErrType(errinfo->errinfo_common.specifier).c_str());
|
|
|
|
|
|
|
|
- switch (errinfo->specifier) {
|
|
|
|
|
- case ErrSpecifier0:
|
|
|
|
|
- case ErrSpecifier1: {
|
|
|
|
|
- const auto& errtype = errinfo->errtype1;
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errtype.address);
|
|
|
|
|
-
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
|
|
|
|
|
|
|
+ // Generic Info
|
|
|
|
|
+ LogGenericInfo(errinfo->errinfo_common);
|
|
|
|
|
+
|
|
|
|
|
+ switch (static_cast<FatalErrType>(errinfo->errinfo_common.specifier)) {
|
|
|
|
|
+ case FatalErrType::Generic:
|
|
|
|
|
+ case FatalErrType::Corrupted:
|
|
|
|
|
+ case FatalErrType::CardRemoved:
|
|
|
|
|
+ case FatalErrType::Logged: {
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "Datetime: %s", GetCurrentSystemTime().c_str());
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
+ case FatalErrType::Exception: {
|
|
|
|
|
+ const auto& errtype = errinfo->exception;
|
|
|
|
|
+
|
|
|
|
|
+ // Register Info
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "ARM Registers:");
|
|
|
|
|
+ for (u32 index = 0; index < errtype.exception_data.exception_context.arm_regs.size();
|
|
|
|
|
+ ++index) {
|
|
|
|
|
+ if (index < 13) {
|
|
|
|
|
+ LOG_DEBUG(Service_ERR, "r%u=0x%08X", index,
|
|
|
|
|
+ errtype.exception_data.exception_context.arm_regs.at(index));
|
|
|
|
|
+ } else if (index == 13) {
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "SP=0x%08X",
|
|
|
|
|
+ errtype.exception_data.exception_context.arm_regs.at(index));
|
|
|
|
|
+ } else if (index == 14) {
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "LR=0x%08X",
|
|
|
|
|
+ errtype.exception_data.exception_context.arm_regs.at(index));
|
|
|
|
|
+ } else if (index == 15) {
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "PC=0x%08X",
|
|
|
|
|
+ errtype.exception_data.exception_context.arm_regs.at(index));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "CPSR=0x%08X", errtype.exception_data.exception_context.cpsr);
|
|
|
|
|
|
|
|
- case ErrSpecifier3: {
|
|
|
|
|
- const auto& errtype = errinfo->errtype3;
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "TYPE: %s", GetErrInfo3Type(errtype.error_type).c_str());
|
|
|
|
|
-
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "PC: 0x%08X", errtype.pc);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "LR: 0x%08X", errtype.lr);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "SP: 0x%08X", errtype.sp);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "CPSR: 0x%08X", errtype.cpsr);
|
|
|
|
|
-
|
|
|
|
|
- switch (errtype.error_type) {
|
|
|
|
|
- case PrefetchAbort:
|
|
|
|
|
- case DataAbort:
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "Fault Address: 0x%08X", errtype.fault_addr);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "Fault Status Register: 0x%08X", errtype.fault_status_reg);
|
|
|
|
|
|
|
+ // Exception Info
|
|
|
|
|
+ LOG_CRITICAL(
|
|
|
|
|
+ Service_ERR, "EXCEPTION TYPE: %s",
|
|
|
|
|
+ GetExceptionType(errtype.exception_data.exception_info.exception_type).c_str());
|
|
|
|
|
+ switch (static_cast<ExceptionType>(errtype.exception_data.exception_info.exception_type)) {
|
|
|
|
|
+ case ExceptionType::PrefetchAbort:
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "IFSR: 0x%08X", errtype.exception_data.exception_info.sr);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "r15: 0x%08X", errtype.exception_data.exception_info.ar);
|
|
|
|
|
+ case ExceptionType::DataAbort:
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "DFSR: 0x%08X", errtype.exception_data.exception_info.sr);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "DFAR: 0x%08X", errtype.exception_data.exception_info.ar);
|
|
|
break;
|
|
break;
|
|
|
- case VectorFP:
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "FPEXC: 0x%08X", errtype.fpexc);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "FINST: 0x%08X", errtype.finst);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "FINST2: 0x%08X", errtype.finst2);
|
|
|
|
|
|
|
+ case ExceptionType::VectorFP:
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "FPEXC: 0x%08X",
|
|
|
|
|
+ errtype.exception_data.exception_info.fpinst);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "FINST: 0x%08X",
|
|
|
|
|
+ errtype.exception_data.exception_info.fpinst);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "FINST2: 0x%08X",
|
|
|
|
|
+ errtype.exception_data.exception_info.fpinst2);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "Datetime: %s", GetCurrentSystemTime().c_str());
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- case ErrSpecifier4: {
|
|
|
|
|
- const auto& errtype = errinfo->errtype4;
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
|
|
|
|
|
|
|
+ case FatalErrType::ResultFailure: {
|
|
|
|
|
+ const auto& errtype = errinfo->result_failure;
|
|
|
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
|
|
|
|
|
-
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string1);
|
|
|
|
|
- LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string2);
|
|
|
|
|
|
|
+ // Failure Message
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "Failure Message: %s", errtype.message);
|
|
|
|
|
+ LOG_CRITICAL(Service_ERR, "Datetime: %s", GetCurrentSystemTime().c_str());
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- cmd_buff[1] = 0; // No error
|
|
|
|
|
|
|
+ } // switch FatalErrType
|
|
|
|
|
+
|
|
|
|
|
+ cmd_buff[0] = IPC::MakeHeader(0x1, 1, 0);
|
|
|
|
|
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const Interface::FunctionInfo FunctionTable[] = {
|
|
const Interface::FunctionInfo FunctionTable[] = {
|
|
|
|
|
+ // clang-format off
|
|
|
{0x00010800, ThrowFatalError, "ThrowFatalError"},
|
|
{0x00010800, ThrowFatalError, "ThrowFatalError"},
|
|
|
|
|
+ {0x00020042, nullptr, "SetUserString"},
|
|
|
|
|
+ // clang-format on
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|