fatal/creport: Add cpu context.

This commit is contained in:
Michael Scire 2018-11-13 20:22:54 -08:00
parent 50c65ea7e1
commit 9714db14d2
15 changed files with 60 additions and 20 deletions

View file

@ -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];

View file

@ -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;

View file

@ -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);

View file

@ -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);
}
}

View file

@ -22,7 +22,7 @@
#include "creport_code_info.hpp"
class ThreadInfo {
private:
public:
ThreadContext context{};
u64 thread_id = 0;
u64 stack_top = 0;

View file

@ -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);

View file

@ -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);

View file

@ -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";

View file

@ -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";

View file

@ -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";

View file

@ -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) {

View file

@ -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";

View file

@ -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";

View file

@ -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:

View file

@ -96,8 +96,9 @@ struct FatalCpuContext {
u32 type;
};
struct FatalContext {
struct FatalThrowContext {
u32 error_code;
bool is_creport;
FatalCpuContext cpu_ctx;
};