From 7d3a5288717b292c6ef4a90b00923c4cf57d10e6 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 23 Nov 2017 18:37:08 +0300 Subject: [PATCH] Use Qt for error reports --- Utilities/Log.cpp | 18 ++++++++++++- Utilities/Thread.cpp | 31 ---------------------- Utilities/Thread.h | 3 +++ rpcs3/main.cpp | 50 +++++++++++++++++++++++++++++++++++ rpcs3/rpcs3qt/main_window.cpp | 10 ++++--- 5 files changed, 77 insertions(+), 35 deletions(-) diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index e41a6a5834..5f53bb9975 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -367,9 +367,15 @@ logs::file_writer::file_writer(const std::string& name) m_fout2.close(); } } + catch (const std::exception& e) + { + std::thread([text = std::string{e.what()}]{ report_fatal_error(text); }).detach(); + return; + } catch (...) { - catch_all_exceptions(); + std::thread([]{ report_fatal_error("Unknown error" HERE); }).detach(); + return; } m_writer = std::thread([this]() @@ -402,6 +408,11 @@ logs::file_writer::file_writer(const std::string& name) logs::file_writer::~file_writer() { + if (!m_fptr) + { + return; + } + // Stop writer thread while (m_out << 24 < m_buf) { @@ -487,6 +498,11 @@ bool logs::file_writer::flush(u64 bufv) void logs::file_writer::log(logs::level sev, const char* text, std::size_t size) { + if (!m_fptr) + { + return; + } + // TODO: write bigger fragment directly in blocking manner while (size && size <= 0xffffff) { diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 2682ed008b..bb10f7c94a 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -37,32 +37,6 @@ thread_local u64 g_tls_fault_all = 0; thread_local u64 g_tls_fault_rsx = 0; thread_local u64 g_tls_fault_spu = 0; -static void report_fatal_error(const std::string& msg) -{ - static semaphore<> g_report_only_once; - - g_report_only_once.wait(); - - std::string _msg = msg + "\n" - "HOW TO REPORT ERRORS: https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support\n" - "Please, don't send incorrect reports. Thanks for understanding.\n"; - -#ifdef _WIN32 - _msg += "\nPress Yes or Enter to visit the URL above immediately."; - const std::size_t buf_size = _msg.size() + 1; - const int size = static_cast(buf_size); - std::unique_ptr buffer(new wchar_t[buf_size]); - MultiByteToWideChar(CP_UTF8, 0, _msg.c_str(), size, buffer.get(), size); - - if (MessageBoxW(0, buffer.get(), L"Fatal error", MB_ICONERROR | MB_YESNO) == IDYES) - { - ShellExecuteW(0, L"open", L"https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support", 0, 0, SW_SHOWNORMAL); - } -#else - std::printf("Fatal error: \n%s", _msg.c_str()); -#endif -} - [[noreturn]] void catch_all_exceptions() { try @@ -77,8 +51,6 @@ static void report_fatal_error(const std::string& msg) { report_fatal_error("Unhandled exception (unknown)"); } - - std::abort(); } enum x64_reg_t : u32 @@ -1497,13 +1469,11 @@ const bool s_exception_handler_set = []() -> bool if (!AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)exception_handler)) { report_fatal_error("AddVectoredExceptionHandler() failed."); - std::abort(); } if (!SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exception_filter)) { report_fatal_error("SetUnhandledExceptionFilter() failed."); - std::abort(); } return true; @@ -1550,7 +1520,6 @@ static void signal_handler(int sig, siginfo_t* info, void* uct) // TODO (debugger interaction) report_fatal_error(fmt::format("Segfault %s location %p at %p.", cause, info->si_addr, RIP(context))); - std::abort(); } const bool s_exception_handler_set = []() -> bool diff --git a/Utilities/Thread.h b/Utilities/Thread.h index a3bd00980d..031ac9eecc 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -10,6 +10,9 @@ #include "sema.h" #include "cond.h" +// Report error and call std::abort(), defined in main.cpp +[[noreturn]] void report_fatal_error(const std::string&); + // Will report exception and call std::abort() if put in catch(...) [[noreturn]] void catch_all_exceptions(); diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp index 5a8e4fda9e..609fececfc 100644 --- a/rpcs3/main.cpp +++ b/rpcs3/main.cpp @@ -5,19 +5,65 @@ #include #include #include +#include #include "rpcs3_app.h" +#include "Utilities/sema.h" #ifdef _WIN32 #include #endif inline std::string sstr(const QString& _in) { return _in.toUtf8().toStdString(); } +template +inline auto tr(Args&&... args) +{ + return QObject::tr(std::forward(args)...); +} + namespace logs { void set_init(); } +static semaphore<> s_init{0}; +static semaphore<> s_qt_init{0}; +static semaphore<> s_qt_mutex{}; + +[[noreturn]] extern void report_fatal_error(const std::string& text) +{ + s_qt_mutex.wait(); + + if (!s_qt_init.try_wait()) + { + s_init.wait(); + static int argc = 1; + static char arg1[] = {"ERROR"}; + static char* argv[] = {arg1}; + static QApplication app0{argc, argv}; + } + + QMessageBox msg; + msg.setWindowTitle(tr("RPCS3: Fatal Error")); + msg.setIcon(QMessageBox::Critical); + msg.setTextFormat(Qt::RichText); + msg.setText(QString(R"( +

+ %1
+ %2
+ https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support
+ %3
+

+ )") + .arg(Qt::convertFromPlainText(QString::fromStdString(text))) + .arg(tr("HOW TO REPORT ERRORS:")) + .arg(tr("Please, don't send incorrect reports. Thanks for understanding."))); + msg.layout()->setSizeConstraint(QLayout::SetFixedSize); + msg.exec(); + + std::abort(); +} + int main(int argc, char** argv) { logs::set_init(); @@ -41,6 +87,8 @@ int main(int argc, char** argv) QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + s_init.post(); + s_qt_mutex.wait(); rpcs3_app app(argc, argv); // Command line args @@ -79,5 +127,7 @@ int main(int argc, char** argv) }); } + s_qt_init.post(); + s_qt_mutex.post(); return app.exec(); } diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 87a9319c3b..2413fb624d 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -127,12 +127,12 @@ void main_window::Init() LOG_WARNING(GENERAL, "Experimental Build Warning! Build origin: " STRINGIZE(BRANCH)); QMessageBox msg; - msg.setWindowTitle("Experimental Build Warning"); + msg.setWindowTitle(tr("Experimental Build Warning")); msg.setIcon(QMessageBox::Critical); msg.setTextFormat(Qt::RichText); msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msg.setDefaultButton(QMessageBox::No); - msg.setText(QString( + msg.setText(QString(tr( R"(

Please understand that this build is not an official RPCS3 release.
@@ -142,7 +142,7 @@ void main_window::Init() Do you wish to use this build anyway?

)" - ).arg(STRINGIZE(BRANCH))); + )).arg(Qt::convertFromPlainText(STRINGIZE(BRANCH)))); msg.layout()->setSizeConstraint(QLayout::SetFixedSize); if (msg.exec() == QMessageBox::No) @@ -416,6 +416,10 @@ void main_window::InstallPkg(const QString& dropPath) LOG_SUCCESS(GENERAL, "Successfully installed %s.", fileName); guiSettings->ShowInfoBox(gui::ib_pkg_success, tr("Success!"), tr("Successfully installed software from package!"), this); } + +#ifdef _WIN32 + taskbar_progress->hide(); +#endif } void main_window::InstallPup(const QString& dropPath)