diff options
| author | 2019-06-21 14:05:18 -0400 | |
|---|---|---|
| committer | 2019-06-21 14:05:18 -0400 | |
| commit | 96412848a9db0643198ea882824688f23dc19606 (patch) | |
| tree | 2824eafaf4bc026cc3fc0ee498d1c5c623f3aa65 /src/core/hle | |
| parent | Merge pull request #2291 from DarkLordZach/homebrew-testing (diff) | |
| parent | loader: Move NSO module tracking to AppLoader (diff) | |
| download | yuzu-96412848a9db0643198ea882824688f23dc19606.tar.gz yuzu-96412848a9db0643198ea882824688f23dc19606.tar.xz yuzu-96412848a9db0643198ea882824688f23dc19606.zip | |
Merge pull request #2482 from DarkLordZach/prepo
core: Add detailed local reporting feature for development
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/applets.cpp | 34 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/applets.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/error.cpp | 19 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/general_backend.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/general_backend.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/fatal/fatal.cpp | 26 | ||||
| -rw-r--r-- | src/core/hle/service/prepo/prepo.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 3 |
9 files changed, 102 insertions, 44 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f9c606bc5..de6363ff2 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include "core/hle/result.h" | 38 | #include "core/hle/result.h" |
| 39 | #include "core/hle/service/service.h" | 39 | #include "core/hle/service/service.h" |
| 40 | #include "core/memory.h" | 40 | #include "core/memory.h" |
| 41 | #include "core/reporter.h" | ||
| 41 | 42 | ||
| 42 | namespace Kernel { | 43 | namespace Kernel { |
| 43 | namespace { | 44 | namespace { |
| @@ -594,6 +595,7 @@ struct BreakReason { | |||
| 594 | static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | 595 | static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { |
| 595 | BreakReason break_reason{reason}; | 596 | BreakReason break_reason{reason}; |
| 596 | bool has_dumped_buffer{}; | 597 | bool has_dumped_buffer{}; |
| 598 | std::vector<u8> debug_buffer; | ||
| 597 | 599 | ||
| 598 | const auto handle_debug_buffer = [&](VAddr addr, u64 sz) { | 600 | const auto handle_debug_buffer = [&](VAddr addr, u64 sz) { |
| 599 | if (sz == 0 || addr == 0 || has_dumped_buffer) { | 601 | if (sz == 0 || addr == 0 || has_dumped_buffer) { |
| @@ -605,7 +607,7 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 605 | LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", Memory::Read32(addr)); | 607 | LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", Memory::Read32(addr)); |
| 606 | } else { | 608 | } else { |
| 607 | // We don't know what's in here so we'll hexdump it | 609 | // We don't know what's in here so we'll hexdump it |
| 608 | std::vector<u8> debug_buffer(sz); | 610 | debug_buffer.resize(sz); |
| 609 | Memory::ReadBlock(addr, debug_buffer.data(), sz); | 611 | Memory::ReadBlock(addr, debug_buffer.data(), sz); |
| 610 | std::string hexdump; | 612 | std::string hexdump; |
| 611 | for (std::size_t i = 0; i < debug_buffer.size(); i++) { | 613 | for (std::size_t i = 0; i < debug_buffer.size(); i++) { |
| @@ -664,6 +666,10 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 664 | break; | 666 | break; |
| 665 | } | 667 | } |
| 666 | 668 | ||
| 669 | system.GetReporter().SaveSvcBreakReport( | ||
| 670 | static_cast<u32>(break_reason.break_type.Value()), break_reason.signal_debugger, info1, | ||
| 671 | info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt); | ||
| 672 | |||
| 667 | if (!break_reason.signal_debugger) { | 673 | if (!break_reason.signal_debugger) { |
| 668 | LOG_CRITICAL( | 674 | LOG_CRITICAL( |
| 669 | Debug_Emulated, | 675 | Debug_Emulated, |
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 14fa92318..e3e4ead03 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp | |||
| @@ -35,12 +35,28 @@ AppletDataBroker::AppletDataBroker() { | |||
| 35 | 35 | ||
| 36 | AppletDataBroker::~AppletDataBroker() = default; | 36 | AppletDataBroker::~AppletDataBroker() = default; |
| 37 | 37 | ||
| 38 | AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const { | ||
| 39 | std::vector<std::vector<u8>> out_normal; | ||
| 40 | |||
| 41 | for (const auto& storage : in_channel) { | ||
| 42 | out_normal.push_back(storage->GetData()); | ||
| 43 | } | ||
| 44 | |||
| 45 | std::vector<std::vector<u8>> out_interactive; | ||
| 46 | |||
| 47 | for (const auto& storage : in_interactive_channel) { | ||
| 48 | out_interactive.push_back(storage->GetData()); | ||
| 49 | } | ||
| 50 | |||
| 51 | return {std::move(out_normal), std::move(out_interactive)}; | ||
| 52 | } | ||
| 53 | |||
| 38 | std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { | 54 | std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { |
| 39 | if (out_channel.empty()) | 55 | if (out_channel.empty()) |
| 40 | return nullptr; | 56 | return nullptr; |
| 41 | 57 | ||
| 42 | auto out = std::move(out_channel.front()); | 58 | auto out = std::move(out_channel.front()); |
| 43 | out_channel.pop(); | 59 | out_channel.pop_front(); |
| 44 | return out; | 60 | return out; |
| 45 | } | 61 | } |
| 46 | 62 | ||
| @@ -49,7 +65,7 @@ std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() { | |||
| 49 | return nullptr; | 65 | return nullptr; |
| 50 | 66 | ||
| 51 | auto out = std::move(in_channel.front()); | 67 | auto out = std::move(in_channel.front()); |
| 52 | in_channel.pop(); | 68 | in_channel.pop_front(); |
| 53 | return out; | 69 | return out; |
| 54 | } | 70 | } |
| 55 | 71 | ||
| @@ -58,7 +74,7 @@ std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() { | |||
| 58 | return nullptr; | 74 | return nullptr; |
| 59 | 75 | ||
| 60 | auto out = std::move(out_interactive_channel.front()); | 76 | auto out = std::move(out_interactive_channel.front()); |
| 61 | out_interactive_channel.pop(); | 77 | out_interactive_channel.pop_front(); |
| 62 | return out; | 78 | return out; |
| 63 | } | 79 | } |
| 64 | 80 | ||
| @@ -67,25 +83,25 @@ std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() { | |||
| 67 | return nullptr; | 83 | return nullptr; |
| 68 | 84 | ||
| 69 | auto out = std::move(in_interactive_channel.front()); | 85 | auto out = std::move(in_interactive_channel.front()); |
| 70 | in_interactive_channel.pop(); | 86 | in_interactive_channel.pop_front(); |
| 71 | return out; | 87 | return out; |
| 72 | } | 88 | } |
| 73 | 89 | ||
| 74 | void AppletDataBroker::PushNormalDataFromGame(IStorage storage) { | 90 | void AppletDataBroker::PushNormalDataFromGame(IStorage storage) { |
| 75 | in_channel.push(std::make_unique<IStorage>(storage)); | 91 | in_channel.push_back(std::make_unique<IStorage>(storage)); |
| 76 | } | 92 | } |
| 77 | 93 | ||
| 78 | void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) { | 94 | void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) { |
| 79 | out_channel.push(std::make_unique<IStorage>(storage)); | 95 | out_channel.push_back(std::make_unique<IStorage>(storage)); |
| 80 | pop_out_data_event.writable->Signal(); | 96 | pop_out_data_event.writable->Signal(); |
| 81 | } | 97 | } |
| 82 | 98 | ||
| 83 | void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) { | 99 | void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) { |
| 84 | in_interactive_channel.push(std::make_unique<IStorage>(storage)); | 100 | in_interactive_channel.push_back(std::make_unique<IStorage>(storage)); |
| 85 | } | 101 | } |
| 86 | 102 | ||
| 87 | void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) { | 103 | void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) { |
| 88 | out_interactive_channel.push(std::make_unique<IStorage>(storage)); | 104 | out_interactive_channel.push_back(std::make_unique<IStorage>(storage)); |
| 89 | pop_interactive_out_data_event.writable->Signal(); | 105 | pop_interactive_out_data_event.writable->Signal(); |
| 90 | } | 106 | } |
| 91 | 107 | ||
| @@ -204,7 +220,7 @@ std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const { | |||
| 204 | UNIMPLEMENTED_MSG( | 220 | UNIMPLEMENTED_MSG( |
| 205 | "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", | 221 | "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", |
| 206 | static_cast<u8>(id)); | 222 | static_cast<u8>(id)); |
| 207 | return std::make_shared<StubApplet>(); | 223 | return std::make_shared<StubApplet>(id); |
| 208 | } | 224 | } |
| 209 | } | 225 | } |
| 210 | 226 | ||
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index b46e10a4a..05ae739ca 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -54,6 +54,14 @@ public: | |||
| 54 | AppletDataBroker(); | 54 | AppletDataBroker(); |
| 55 | ~AppletDataBroker(); | 55 | ~AppletDataBroker(); |
| 56 | 56 | ||
| 57 | struct RawChannelData { | ||
| 58 | std::vector<std::vector<u8>> normal; | ||
| 59 | std::vector<std::vector<u8>> interactive; | ||
| 60 | }; | ||
| 61 | |||
| 62 | // Retrieves but does not pop the data sent to applet. | ||
| 63 | RawChannelData PeekDataToAppletForDebug() const; | ||
| 64 | |||
| 57 | std::unique_ptr<IStorage> PopNormalDataToGame(); | 65 | std::unique_ptr<IStorage> PopNormalDataToGame(); |
| 58 | std::unique_ptr<IStorage> PopNormalDataToApplet(); | 66 | std::unique_ptr<IStorage> PopNormalDataToApplet(); |
| 59 | 67 | ||
| @@ -76,16 +84,16 @@ private: | |||
| 76 | // Queues are named from applet's perspective | 84 | // Queues are named from applet's perspective |
| 77 | 85 | ||
| 78 | // PopNormalDataToApplet and PushNormalDataFromGame | 86 | // PopNormalDataToApplet and PushNormalDataFromGame |
| 79 | std::queue<std::unique_ptr<IStorage>> in_channel; | 87 | std::deque<std::unique_ptr<IStorage>> in_channel; |
| 80 | 88 | ||
| 81 | // PopNormalDataToGame and PushNormalDataFromApplet | 89 | // PopNormalDataToGame and PushNormalDataFromApplet |
| 82 | std::queue<std::unique_ptr<IStorage>> out_channel; | 90 | std::deque<std::unique_ptr<IStorage>> out_channel; |
| 83 | 91 | ||
| 84 | // PopInteractiveDataToApplet and PushInteractiveDataFromGame | 92 | // PopInteractiveDataToApplet and PushInteractiveDataFromGame |
| 85 | std::queue<std::unique_ptr<IStorage>> in_interactive_channel; | 93 | std::deque<std::unique_ptr<IStorage>> in_interactive_channel; |
| 86 | 94 | ||
| 87 | // PopInteractiveDataToGame and PushInteractiveDataFromApplet | 95 | // PopInteractiveDataToGame and PushInteractiveDataFromApplet |
| 88 | std::queue<std::unique_ptr<IStorage>> out_interactive_channel; | 96 | std::deque<std::unique_ptr<IStorage>> out_interactive_channel; |
| 89 | 97 | ||
| 90 | Kernel::EventPair state_changed_event; | 98 | Kernel::EventPair state_changed_event; |
| 91 | 99 | ||
diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index 04774bedc..af3a900f8 100644 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp | |||
| @@ -9,8 +9,10 @@ | |||
| 9 | #include "common/string_util.h" | 9 | #include "common/string_util.h" |
| 10 | #include "core/core.h" | 10 | #include "core/core.h" |
| 11 | #include "core/frontend/applets/error.h" | 11 | #include "core/frontend/applets/error.h" |
| 12 | #include "core/hle/kernel/process.h" | ||
| 12 | #include "core/hle/service/am/am.h" | 13 | #include "core/hle/service/am/am.h" |
| 13 | #include "core/hle/service/am/applets/error.h" | 14 | #include "core/hle/service/am/applets/error.h" |
| 15 | #include "core/reporter.h" | ||
| 14 | 16 | ||
| 15 | namespace Service::AM::Applets { | 17 | namespace Service::AM::Applets { |
| 16 | 18 | ||
| @@ -143,9 +145,12 @@ void Error::Execute() { | |||
| 143 | } | 145 | } |
| 144 | 146 | ||
| 145 | const auto callback = [this] { DisplayCompleted(); }; | 147 | const auto callback = [this] { DisplayCompleted(); }; |
| 148 | const auto title_id = Core::CurrentProcess()->GetTitleID(); | ||
| 149 | const auto& reporter{Core::System::GetInstance().GetReporter()}; | ||
| 146 | 150 | ||
| 147 | switch (mode) { | 151 | switch (mode) { |
| 148 | case ErrorAppletMode::ShowError: | 152 | case ErrorAppletMode::ShowError: |
| 153 | reporter.SaveErrorReport(title_id, error_code); | ||
| 149 | frontend.ShowError(error_code, callback); | 154 | frontend.ShowError(error_code, callback); |
| 150 | break; | 155 | break; |
| 151 | case ErrorAppletMode::ShowSystemError: | 156 | case ErrorAppletMode::ShowSystemError: |
| @@ -156,14 +161,18 @@ void Error::Execute() { | |||
| 156 | const auto& detail_text = | 161 | const auto& detail_text = |
| 157 | system ? args->system_error.detail_text : args->application_error.detail_text; | 162 | system ? args->system_error.detail_text : args->application_error.detail_text; |
| 158 | 163 | ||
| 159 | frontend.ShowCustomErrorText( | 164 | const auto main_text_string = |
| 160 | error_code, | 165 | Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size()); |
| 161 | Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size()), | 166 | const auto detail_text_string = |
| 162 | Common::StringFromFixedZeroTerminatedBuffer(detail_text.data(), detail_text.size()), | 167 | Common::StringFromFixedZeroTerminatedBuffer(detail_text.data(), detail_text.size()); |
| 163 | callback); | 168 | |
| 169 | reporter.SaveErrorReport(title_id, error_code, main_text_string, detail_text_string); | ||
| 170 | frontend.ShowCustomErrorText(error_code, main_text_string, detail_text_string, callback); | ||
| 164 | break; | 171 | break; |
| 165 | } | 172 | } |
| 166 | case ErrorAppletMode::ShowErrorRecord: | 173 | case ErrorAppletMode::ShowErrorRecord: |
| 174 | reporter.SaveErrorReport(title_id, error_code, | ||
| 175 | fmt::format("{:016X}", args->error_record.posix_time)); | ||
| 167 | frontend.ShowErrorWithTimestamp( | 176 | frontend.ShowErrorWithTimestamp( |
| 168 | error_code, std::chrono::seconds{args->error_record.posix_time}, callback); | 177 | error_code, std::chrono::seconds{args->error_record.posix_time}, callback); |
| 169 | break; | 178 | break; |
diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp index 76fc8906d..54c155dd8 100644 --- a/src/core/hle/service/am/applets/general_backend.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "core/hle/result.h" | 13 | #include "core/hle/result.h" |
| 14 | #include "core/hle/service/am/am.h" | 14 | #include "core/hle/service/am/am.h" |
| 15 | #include "core/hle/service/am/applets/general_backend.h" | 15 | #include "core/hle/service/am/applets/general_backend.h" |
| 16 | #include "core/reporter.h" | ||
| 16 | 17 | ||
| 17 | namespace Service::AM::Applets { | 18 | namespace Service::AM::Applets { |
| 18 | 19 | ||
| @@ -83,13 +84,20 @@ void PhotoViewer::ViewFinished() { | |||
| 83 | broker.SignalStateChanged(); | 84 | broker.SignalStateChanged(); |
| 84 | } | 85 | } |
| 85 | 86 | ||
| 86 | StubApplet::StubApplet() = default; | 87 | StubApplet::StubApplet(AppletId id) : id(id) {} |
| 87 | 88 | ||
| 88 | StubApplet::~StubApplet() = default; | 89 | StubApplet::~StubApplet() = default; |
| 89 | 90 | ||
| 90 | void StubApplet::Initialize() { | 91 | void StubApplet::Initialize() { |
| 91 | LOG_WARNING(Service_AM, "called (STUBBED)"); | 92 | LOG_WARNING(Service_AM, "called (STUBBED)"); |
| 92 | Applet::Initialize(); | 93 | Applet::Initialize(); |
| 94 | |||
| 95 | const auto data = broker.PeekDataToAppletForDebug(); | ||
| 96 | Core::System::GetInstance().GetReporter().SaveUnimplementedAppletReport( | ||
| 97 | static_cast<u32>(id), common_args.arguments_version, common_args.library_version, | ||
| 98 | common_args.theme_color, common_args.play_startup_sound, common_args.system_tick, | ||
| 99 | data.normal, data.interactive); | ||
| 100 | |||
| 93 | LogCurrentStorage(broker, "Initialize"); | 101 | LogCurrentStorage(broker, "Initialize"); |
| 94 | } | 102 | } |
| 95 | 103 | ||
diff --git a/src/core/hle/service/am/applets/general_backend.h b/src/core/hle/service/am/applets/general_backend.h index 2dd255d7c..fb68a2543 100644 --- a/src/core/hle/service/am/applets/general_backend.h +++ b/src/core/hle/service/am/applets/general_backend.h | |||
| @@ -34,7 +34,7 @@ private: | |||
| 34 | 34 | ||
| 35 | class StubApplet final : public Applet { | 35 | class StubApplet final : public Applet { |
| 36 | public: | 36 | public: |
| 37 | StubApplet(); | 37 | explicit StubApplet(AppletId id); |
| 38 | ~StubApplet() override; | 38 | ~StubApplet() override; |
| 39 | 39 | ||
| 40 | void Initialize() override; | 40 | void Initialize() override; |
| @@ -43,6 +43,9 @@ public: | |||
| 43 | ResultCode GetStatus() const override; | 43 | ResultCode GetStatus() const override; |
| 44 | void ExecuteInteractive() override; | 44 | void ExecuteInteractive() override; |
| 45 | void Execute() override; | 45 | void Execute() override; |
| 46 | |||
| 47 | private: | ||
| 48 | AppletId id; | ||
| 46 | }; | 49 | }; |
| 47 | 50 | ||
| 48 | } // namespace Service::AM::Applets | 51 | } // namespace Service::AM::Applets |
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 2c229bcad..fe49c2161 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include "core/hle/service/fatal/fatal.h" | 16 | #include "core/hle/service/fatal/fatal.h" |
| 17 | #include "core/hle/service/fatal/fatal_p.h" | 17 | #include "core/hle/service/fatal/fatal_p.h" |
| 18 | #include "core/hle/service/fatal/fatal_u.h" | 18 | #include "core/hle/service/fatal/fatal_u.h" |
| 19 | #include "core/reporter.h" | ||
| 19 | 20 | ||
| 20 | namespace Service::Fatal { | 21 | namespace Service::Fatal { |
| 21 | 22 | ||
| @@ -100,27 +101,10 @@ static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) { | |||
| 100 | 101 | ||
| 101 | LOG_ERROR(Service_Fatal, "{}", crash_report); | 102 | LOG_ERROR(Service_Fatal, "{}", crash_report); |
| 102 | 103 | ||
| 103 | const std::string crashreport_dir = | 104 | Core::System::GetInstance().GetReporter().SaveCrashReport( |
| 104 | FileUtil::GetUserPath(FileUtil::UserPath::LogDir) + "crash_logs"; | 105 | title_id, error_code, info.set_flags, info.program_entry_point, info.sp, info.pc, |
| 105 | 106 | info.pstate, info.afsr0, info.afsr1, info.esr, info.far, info.registers, info.backtrace, | |
| 106 | if (!FileUtil::CreateFullPath(crashreport_dir)) { | 107 | info.backtrace_size, info.ArchAsString(), info.unk10); |
| 107 | LOG_ERROR( | ||
| 108 | Service_Fatal, | ||
| 109 | "Unable to create crash report directory. Possible log directory permissions issue."); | ||
| 110 | return; | ||
| 111 | } | ||
| 112 | |||
| 113 | const std::time_t t = std::time(nullptr); | ||
| 114 | const std::string crashreport_filename = | ||
| 115 | fmt::format("{}/{:016x}-{:%F-%H%M%S}.log", crashreport_dir, title_id, *std::localtime(&t)); | ||
| 116 | |||
| 117 | auto file = FileUtil::IOFile(crashreport_filename, "wb"); | ||
| 118 | if (file.IsOpen()) { | ||
| 119 | file.WriteString(crash_report); | ||
| 120 | LOG_ERROR(Service_Fatal, "Saving error report to {}", crashreport_filename); | ||
| 121 | } else { | ||
| 122 | LOG_ERROR(Service_Fatal, "Failed to save error report to {}", crashreport_filename); | ||
| 123 | } | ||
| 124 | } | 108 | } |
| 125 | 109 | ||
| 126 | static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const FatalInfo& info) { | 110 | static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const FatalInfo& info) { |
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index e4fcee9f8..7e134f5c1 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp | |||
| @@ -2,10 +2,18 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <json.hpp> | ||
| 6 | #include "common/file_util.h" | ||
| 7 | #include "common/hex_util.h" | ||
| 5 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "common/scm_rev.h" | ||
| 6 | #include "core/hle/ipc_helpers.h" | 10 | #include "core/hle/ipc_helpers.h" |
| 11 | #include "core/hle/kernel/process.h" | ||
| 12 | #include "core/hle/service/acc/profile_manager.h" | ||
| 7 | #include "core/hle/service/prepo/prepo.h" | 13 | #include "core/hle/service/prepo/prepo.h" |
| 8 | #include "core/hle/service/service.h" | 14 | #include "core/hle/service/service.h" |
| 15 | #include "core/reporter.h" | ||
| 16 | #include "core/settings.h" | ||
| 9 | 17 | ||
| 10 | namespace Service::PlayReport { | 18 | namespace Service::PlayReport { |
| 11 | 19 | ||
| @@ -40,8 +48,21 @@ public: | |||
| 40 | 48 | ||
| 41 | private: | 49 | private: |
| 42 | void SaveReportWithUserOld(Kernel::HLERequestContext& ctx) { | 50 | void SaveReportWithUserOld(Kernel::HLERequestContext& ctx) { |
| 43 | // TODO(ogniK): Do we want to add play report? | 51 | IPC::RequestParser rp{ctx}; |
| 44 | LOG_WARNING(Service_PREPO, "(STUBBED) called"); | 52 | const auto user_id = rp.PopRaw<u128>(); |
| 53 | const auto process_id = rp.PopRaw<u64>(); | ||
| 54 | |||
| 55 | const auto data1 = ctx.ReadBuffer(0); | ||
| 56 | const auto data2 = ctx.ReadBuffer(1); | ||
| 57 | |||
| 58 | LOG_DEBUG( | ||
| 59 | Service_PREPO, | ||
| 60 | "called, user_id={:016X}{:016X}, unk1={:016X}, data1_size={:016X}, data2_size={:016X}", | ||
| 61 | user_id[1], user_id[0], process_id, data1.size(), data2.size()); | ||
| 62 | |||
| 63 | const auto& reporter{Core::System::GetInstance().GetReporter()}; | ||
| 64 | reporter.SavePlayReport(Core::CurrentProcess()->GetTitleID(), process_id, {data1, data2}, | ||
| 65 | user_id); | ||
| 45 | 66 | ||
| 46 | IPC::ResponseBuilder rb{ctx, 2}; | 67 | IPC::ResponseBuilder rb{ctx, 2}; |
| 47 | rb.Push(RESULT_SUCCESS); | 68 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 6c69f899e..b2954eb34 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -68,6 +68,7 @@ | |||
| 68 | #include "core/hle/service/usb/usb.h" | 68 | #include "core/hle/service/usb/usb.h" |
| 69 | #include "core/hle/service/vi/vi.h" | 69 | #include "core/hle/service/vi/vi.h" |
| 70 | #include "core/hle/service/wlan/wlan.h" | 70 | #include "core/hle/service/wlan/wlan.h" |
| 71 | #include "core/reporter.h" | ||
| 71 | 72 | ||
| 72 | namespace Service { | 73 | namespace Service { |
| 73 | 74 | ||
| @@ -148,6 +149,8 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext | |||
| 148 | } | 149 | } |
| 149 | buf.push_back('}'); | 150 | buf.push_back('}'); |
| 150 | 151 | ||
| 152 | Core::System::GetInstance().GetReporter().SaveUnimplementedFunctionReport( | ||
| 153 | ctx, ctx.GetCommand(), function_name, service_name); | ||
| 151 | UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf)); | 154 | UNIMPLEMENTED_MSG("Unknown / unimplemented {}", fmt::to_string(buf)); |
| 152 | } | 155 | } |
| 153 | 156 | ||