summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar bunnei2019-06-21 14:05:18 -0400
committerGravatar GitHub2019-06-21 14:05:18 -0400
commit96412848a9db0643198ea882824688f23dc19606 (patch)
tree2824eafaf4bc026cc3fc0ee498d1c5c623f3aa65 /src/core/hle
parentMerge pull request #2291 from DarkLordZach/homebrew-testing (diff)
parentloader: Move NSO module tracking to AppLoader (diff)
downloadyuzu-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.cpp8
-rw-r--r--src/core/hle/service/am/applets/applets.cpp34
-rw-r--r--src/core/hle/service/am/applets/applets.h16
-rw-r--r--src/core/hle/service/am/applets/error.cpp19
-rw-r--r--src/core/hle/service/am/applets/general_backend.cpp10
-rw-r--r--src/core/hle/service/am/applets/general_backend.h5
-rw-r--r--src/core/hle/service/fatal/fatal.cpp26
-rw-r--r--src/core/hle/service/prepo/prepo.cpp25
-rw-r--r--src/core/hle/service/service.cpp3
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
42namespace Kernel { 43namespace Kernel {
43namespace { 44namespace {
@@ -594,6 +595,7 @@ struct BreakReason {
594static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { 595static 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
36AppletDataBroker::~AppletDataBroker() = default; 36AppletDataBroker::~AppletDataBroker() = default;
37 37
38AppletDataBroker::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
38std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { 54std::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
74void AppletDataBroker::PushNormalDataFromGame(IStorage storage) { 90void 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
78void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) { 94void 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
83void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) { 99void 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
87void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) { 103void 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
15namespace Service::AM::Applets { 17namespace 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
17namespace Service::AM::Applets { 18namespace Service::AM::Applets {
18 19
@@ -83,13 +84,20 @@ void PhotoViewer::ViewFinished() {
83 broker.SignalStateChanged(); 84 broker.SignalStateChanged();
84} 85}
85 86
86StubApplet::StubApplet() = default; 87StubApplet::StubApplet(AppletId id) : id(id) {}
87 88
88StubApplet::~StubApplet() = default; 89StubApplet::~StubApplet() = default;
89 90
90void StubApplet::Initialize() { 91void 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
35class StubApplet final : public Applet { 35class StubApplet final : public Applet {
36public: 36public:
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
47private:
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
20namespace Service::Fatal { 21namespace 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
126static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const FatalInfo& info) { 110static 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
10namespace Service::PlayReport { 18namespace Service::PlayReport {
11 19
@@ -40,8 +48,21 @@ public:
40 48
41private: 49private:
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
72namespace Service { 73namespace 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