mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-26 22:02:15 +00:00
fatal/creport: Add cpu context.
This commit is contained in:
parent
50c65ea7e1
commit
9714db14d2
15 changed files with 60 additions and 20 deletions
|
@ -28,7 +28,7 @@ struct CodeInfo {
|
|||
};
|
||||
|
||||
class CodeList {
|
||||
private:
|
||||
public:
|
||||
static const size_t max_code_count = 0x10;
|
||||
u32 code_count = 0;
|
||||
CodeInfo code_infos[max_code_count];
|
||||
|
|
|
@ -42,6 +42,35 @@ void CrashReport::BuildReport(u64 pid, bool has_extra_info) {
|
|||
}
|
||||
}
|
||||
|
||||
FatalContext *CrashReport::GetFatalContext() {
|
||||
FatalContext *ctx = new FatalContext;
|
||||
*ctx = (FatalContext){0};
|
||||
|
||||
ctx->is_aarch32 = false;
|
||||
ctx->type = static_cast<u32>(this->exception_info.type);
|
||||
|
||||
for (size_t i = 0; i < 29; i++) {
|
||||
ctx->aarch64_ctx.x[i] = this->crashed_thread_info.context.cpu_gprs[i].x;
|
||||
}
|
||||
ctx->aarch64_ctx.fp = this->crashed_thread_info.context.fp;
|
||||
ctx->aarch64_ctx.lr = this->crashed_thread_info.context.lr;
|
||||
ctx->aarch64_ctx.pc = this->crashed_thread_info.context.pc.x;
|
||||
|
||||
ctx->aarch64_ctx.stack_trace_size = this->crashed_thread_info.stack_trace_size;
|
||||
for (size_t i = 0; i < ctx->aarch64_ctx.stack_trace_size; i++) {
|
||||
ctx->aarch64_ctx.stack_trace[i] = this->crashed_thread_info.stack_trace[i];
|
||||
}
|
||||
|
||||
if (this->code_list.code_count) {
|
||||
ctx->aarch64_ctx.start_address = this->code_list.code_infos[0].start_address;
|
||||
}
|
||||
|
||||
/* For ams fatal... */
|
||||
ctx->aarch64_ctx.afsr0 = this->process_info.title_id;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void CrashReport::ProcessExceptions() {
|
||||
if (!IsOpen()) {
|
||||
return;
|
||||
|
|
|
@ -61,6 +61,7 @@ class CrashReport {
|
|||
|
||||
public:
|
||||
void BuildReport(u64 pid, bool has_extra_info);
|
||||
FatalContext *GetFatalContext();
|
||||
void SaveReport();
|
||||
|
||||
bool IsAddressReadable(u64 address, u64 size, MemoryInfo *mi = NULL);
|
||||
|
|
|
@ -132,7 +132,9 @@ int main(int argc, char **argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
fatalWithType(g_Creport.GetResult(), FatalType_ErrorScreen);
|
||||
FatalContext *ctx = g_Creport.GetFatalContext();
|
||||
|
||||
fatalWithContext(g_Creport.GetResult(), FatalType_ErrorScreen, ctx);
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,7 @@
|
|||
#include "creport_code_info.hpp"
|
||||
|
||||
class ThreadInfo {
|
||||
private:
|
||||
public:
|
||||
ThreadContext context{};
|
||||
u64 thread_id = 0;
|
||||
u64 stack_top = 0;
|
||||
|
|
|
@ -53,7 +53,7 @@ static void RunTask(IFatalTask *task, u32 stack_size = 0x4000) {
|
|||
cur_thread->Start();
|
||||
}
|
||||
|
||||
void RunFatalTasks(FatalContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event) {
|
||||
void RunFatalTasks(FatalThrowContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event) {
|
||||
RunTask(new ErrorReportTask(ctx, title_id, error_report, erpt_event));
|
||||
RunTask(new PowerControlTask(ctx, title_id, erpt_event, battery_event));
|
||||
RunTask(new ShowFatalTask(ctx, title_id, battery_event), 0x10000);
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
|
||||
class IFatalTask {
|
||||
protected:
|
||||
FatalContext *ctx;
|
||||
FatalThrowContext *ctx;
|
||||
u64 title_id;
|
||||
public:
|
||||
IFatalTask(FatalContext *ctx, u64 tid) : ctx(ctx), title_id(tid) { }
|
||||
IFatalTask(FatalThrowContext *ctx, u64 tid) : ctx(ctx), title_id(tid) { }
|
||||
virtual Result Run() = 0;
|
||||
virtual const char *GetName() const = 0;
|
||||
};
|
||||
|
||||
void RunFatalTasks(FatalContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event);
|
||||
void RunFatalTasks(FatalThrowContext *ctx, u64 title_id, bool error_report, Event *erpt_event, Event *battery_event);
|
||||
|
|
|
@ -23,7 +23,7 @@ class AdjustClockTask : public IFatalTask {
|
|||
private:
|
||||
Result AdjustClock();
|
||||
public:
|
||||
AdjustClockTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }
|
||||
AdjustClockTask(FatalThrowContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }
|
||||
virtual Result Run() override;
|
||||
virtual const char *GetName() const override {
|
||||
return "AdjustClockTask";
|
||||
|
|
|
@ -24,7 +24,7 @@ class ErrorReportTask : public IFatalTask {
|
|||
bool create_report;
|
||||
Event *erpt_event;
|
||||
public:
|
||||
ErrorReportTask(FatalContext *ctx, u64 title_id, bool error_report, Event *evt) : IFatalTask(ctx, title_id), create_report(error_report), erpt_event(evt) { }
|
||||
ErrorReportTask(FatalThrowContext *ctx, u64 title_id, bool error_report, Event *evt) : IFatalTask(ctx, title_id), create_report(error_report), erpt_event(evt) { }
|
||||
virtual Result Run() override;
|
||||
virtual const char *GetName() const override {
|
||||
return "WriteErrorReport";
|
||||
|
|
|
@ -27,7 +27,7 @@ class PowerControlTask : public IFatalTask {
|
|||
bool TryShutdown();
|
||||
void MonitorBatteryState();
|
||||
public:
|
||||
PowerControlTask(FatalContext *ctx, u64 title_id, Event *er_evt, Event *bt_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt), battery_event(bt_evt) { }
|
||||
PowerControlTask(FatalThrowContext *ctx, u64 title_id, Event *er_evt, Event *bt_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt), battery_event(bt_evt) { }
|
||||
virtual Result Run() override;
|
||||
virtual const char *GetName() const override {
|
||||
return "PowerControlTask";
|
||||
|
@ -40,7 +40,7 @@ class PowerButtonObserveTask : public IFatalTask {
|
|||
private:
|
||||
void WaitForPowerButton();
|
||||
public:
|
||||
PowerButtonObserveTask(FatalContext *ctx, u64 title_id, Event *er_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt) { }
|
||||
PowerButtonObserveTask(FatalThrowContext *ctx, u64 title_id, Event *er_evt) : IFatalTask(ctx, title_id), erpt_event(er_evt) { }
|
||||
virtual Result Run() override;
|
||||
virtual const char *GetName() const override {
|
||||
return "PowerButtonObserveTask";
|
||||
|
@ -49,7 +49,7 @@ class PowerButtonObserveTask : public IFatalTask {
|
|||
|
||||
class StateTransitionStopTask : public IFatalTask {
|
||||
public:
|
||||
StateTransitionStopTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }
|
||||
StateTransitionStopTask(FatalThrowContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }
|
||||
virtual Result Run() override;
|
||||
virtual const char *GetName() const override {
|
||||
return "StateTransitionStopTask";
|
||||
|
|
|
@ -293,7 +293,7 @@ Result ShowFatalTask::ShowFatal() {
|
|||
}
|
||||
} else {
|
||||
if (this->ctx->cpu_ctx.is_aarch32) {
|
||||
FontManager::PrintFormatLine("Backtrace - Start Address: ");
|
||||
FontManager::Print("Backtrace - Start Address: ");
|
||||
FontManager::PrintMonospaceU32(this->ctx->cpu_ctx.aarch32_ctx.start_address);
|
||||
FontManager::PrintLine("");
|
||||
FontManager::AddSpacingLines(0.5f);
|
||||
|
@ -325,9 +325,10 @@ Result ShowFatalTask::ShowFatal() {
|
|||
FontManager::SetPosition(backtrace_x, FontManager::GetY());
|
||||
}
|
||||
} else {
|
||||
FontManager::PrintFormatLine("Backtrace - Start Address: ");
|
||||
FontManager::Print("Backtrace - Start Address: ");
|
||||
FontManager::PrintMonospaceU64(this->ctx->cpu_ctx.aarch64_ctx.start_address);
|
||||
FontManager::PrintLine("");
|
||||
FontManager::AddSpacingLines(0.5f);
|
||||
for (u32 i = 0; i < Aarch64CpuContext::MaxStackTraceDepth / 2; i++) {
|
||||
u64 bt_cur = 0, bt_next = 0;
|
||||
if (i < this->ctx->cpu_ctx.aarch64_ctx.stack_trace_size) {
|
||||
|
|
|
@ -32,7 +32,7 @@ class ShowFatalTask : public IFatalTask {
|
|||
Result PrepareScreenForDrawing();
|
||||
Result ShowFatal();
|
||||
public:
|
||||
ShowFatalTask(FatalContext *ctx, u64 title_id, Event *evt) : IFatalTask(ctx, title_id), battery_event(evt) { }
|
||||
ShowFatalTask(FatalThrowContext *ctx, u64 title_id, Event *evt) : IFatalTask(ctx, title_id), battery_event(evt) { }
|
||||
virtual Result Run() override;
|
||||
virtual const char *GetName() const override {
|
||||
return "ShowFatal";
|
||||
|
@ -43,7 +43,7 @@ class BacklightControlTask : public IFatalTask {
|
|||
private:
|
||||
void TurnOnBacklight();
|
||||
public:
|
||||
BacklightControlTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }
|
||||
BacklightControlTask(FatalThrowContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }
|
||||
virtual Result Run() override;
|
||||
virtual const char *GetName() const override {
|
||||
return "BacklightControlTask";
|
||||
|
|
|
@ -23,7 +23,7 @@ class StopSoundTask : public IFatalTask {
|
|||
private:
|
||||
void StopSound();
|
||||
public:
|
||||
StopSoundTask(FatalContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }
|
||||
StopSoundTask(FatalThrowContext *ctx, u64 title_id) : IFatalTask(ctx, title_id) { }
|
||||
virtual Result Run() override;
|
||||
virtual const char *GetName() const override {
|
||||
return "SoundTask";
|
||||
|
|
|
@ -42,7 +42,7 @@ Result ThrowFatalForSelf(u32 error) {
|
|||
|
||||
Result ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCpuContext *cpu_ctx) {
|
||||
Result rc = 0;
|
||||
FatalContext ctx;
|
||||
FatalThrowContext ctx;
|
||||
ctx.error_code = error;
|
||||
ctx.cpu_ctx = *cpu_ctx;
|
||||
|
||||
|
@ -52,6 +52,12 @@ Result ThrowFatalImpl(u32 error, u64 pid, FatalType policy, FatalCpuContext *cpu
|
|||
/* Get title id. On failure, it'll be zero. */
|
||||
u64 title_id = 0;
|
||||
pminfoGetTitleId(&title_id, pid);
|
||||
ctx.is_creport = title_id == 0x0100000000000036;
|
||||
|
||||
/* Support for ams creport. TODO: Make this its own command? */
|
||||
if (ctx.is_creport && !cpu_ctx->is_aarch32 && cpu_ctx->aarch64_ctx.afsr0 != 0) {
|
||||
title_id = cpu_ctx->aarch64_ctx.afsr0;
|
||||
}
|
||||
|
||||
switch (policy) {
|
||||
case FatalType_ErrorReport:
|
||||
|
|
|
@ -96,8 +96,9 @@ struct FatalCpuContext {
|
|||
u32 type;
|
||||
};
|
||||
|
||||
struct FatalContext {
|
||||
struct FatalThrowContext {
|
||||
u32 error_code;
|
||||
bool is_creport;
|
||||
FatalCpuContext cpu_ctx;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue