diff --git a/stratosphere/creport/creport.json b/stratosphere/creport/creport.json index 2fdc74d80..5686e7b41 100644 --- a/stratosphere/creport/creport.json +++ b/stratosphere/creport/creport.json @@ -19,7 +19,8 @@ "erpt:c": false, "fatal:u": false, "fsp-srv": false, - "ns:dev": false + "ns:dev": false, + "time:s": true, }, "kernel_capabilities": { "kernel_flags": { diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index 3a353e12a..b098abc58 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -1,9 +1,46 @@ +#include +#include +#include #include + #include "creport_crash_report.hpp" #include "creport_debug_types.hpp" +void CrashReport::EnsureReportDirectories() { + char path[FS_MAX_PATH]; + strcpy(path, "sdmc:/atmosphere"); + mkdir(path, S_IRWXU); + strcat(path, "/crash reports"); + mkdir(path, S_IRWXU); + strcat(path, "/dumps"); + mkdir(path, S_IRWXU); +} + void CrashReport::SaveReport() { /* TODO: Save the report to the SD card. */ + char report_path[FS_MAX_PATH]; + + /* Ensure path exists. */ + EnsureReportDirectories(); + + /* Get a timestamp. */ + u64 timestamp; + if (!GetCurrentTime(×tamp)) { + timestamp = svcGetSystemTick(); + } + + /* Open report file. */ + snprintf(report_path, sizeof(report_path) - 1, "sdmc:/atmosphere/crash reports/%016lx_%016lx.log", timestamp, process_info.title_id), + FILE *f_report = fopen(report_path, "w"); + if (f_report == NULL) { + return; + } + + fprintf(f_report, "Atmosphere Crash Report:\n"); + + /* TODO: Actually report about the crash. */ + + fclose(f_report); } void CrashReport::BuildReport(u64 pid, bool has_extra_info) { @@ -175,4 +212,27 @@ bool CrashReport::IsAddressReadable(u64 address, u64 size, MemoryInfo *o_mi) { } return true; -} \ No newline at end of file +} + +bool GetCurrentTime(u64 *out) { + *out = 0; + + /* Verify that pcv isn't dead. */ + { + Handle dummy; + if (R_SUCCEEDED(smRegisterService(&dummy, "time:s", false, 0x20))) { + svcCloseHandle(dummy); + return false; + } + } + + /* Try to get the current time. */ + bool success = false; + if (R_SUCCEEDED(timeInitialize())) { + if (R_SUCCEEDED(timeGetCurrentTime(TimeType_LocalSystemClock, out))) { + success = true; + } + timeExit(); + } + return success; +} diff --git a/stratosphere/creport/source/creport_crash_report.hpp b/stratosphere/creport/source/creport_crash_report.hpp index 7566fb19d..d9a5bd588 100644 --- a/stratosphere/creport/source/creport_crash_report.hpp +++ b/stratosphere/creport/source/creport_crash_report.hpp @@ -90,4 +90,7 @@ class CrashReport { void ProcessDyingMessage(); void HandleAttachProcess(DebugEventInfo &d); void HandleException(DebugEventInfo &d); + + void EnsureReportDirectories(); + bool GetCurrentTime(u64 *out); }; \ No newline at end of file diff --git a/stratosphere/creport/source/creport_main.cpp b/stratosphere/creport/source/creport_main.cpp index bf257d5b2..692197377 100644 --- a/stratosphere/creport/source/creport_main.cpp +++ b/stratosphere/creport/source/creport_main.cpp @@ -95,6 +95,8 @@ int main(int argc, char **argv) { /* Try to debug the crashed process. */ g_Creport.BuildReport(crashed_pid, argv[1][0] == '1'); if (g_Creport.WasSuccessful()) { + g_Creport.SaveReport(); + if (R_SUCCEEDED(nsdevInitialize())) { nsdevTerminateProcess(crashed_pid); nsdevExit();