diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp
index a442c0a884..d7434a72fc 100644
--- a/Utilities/Thread.cpp
+++ b/Utilities/Thread.cpp
@@ -94,7 +94,7 @@ thread_local bool g_tls_access_violation_recovered = false;
extern thread_local std::string(*g_tls_log_prefix)();
// Report error and call std::abort(), defined in main.cpp
-[[noreturn]] void report_fatal_error(const std::string&);
+[[noreturn]] void report_fatal_error(std::string_view);
template <>
void fmt_class_string::format(std::string& out, u64 arg)
@@ -1609,6 +1609,22 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
return true;
}
+static void append_thread_name(std::string& msg)
+{
+ if (thread_ctrl::get_current())
+ {
+ fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
+ }
+ else if (thread_ctrl::is_main())
+ {
+ fmt::append(msg, "Thread: Main Thread");
+ }
+ else
+ {
+ fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
+ }
+}
+
#ifdef _WIN32
static LONG exception_handler(PEXCEPTION_POINTERS pExp) noexcept
@@ -1670,14 +1686,7 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept
}
}
- if (thread_ctrl::get_current())
- {
- fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
- }
-
- // TODO: Report full thread name if not an emu thread
-
- fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
+ append_thread_name(msg);
std::vector modules;
for (DWORD size = 256; modules.size() != size; size /= sizeof(HMODULE))
@@ -1795,14 +1804,7 @@ static void signal_handler(int /*sig*/, siginfo_t* info, void* uct) noexcept
std::string msg = fmt::format("Segfault %s location %p at %p.\n", cause, info->si_addr, RIP(context));
- if (thread_ctrl::get_current())
- {
- fmt::append(msg, "Emu Thread Name: '%s'.\n", thread_ctrl::get_name());
- }
-
- // TODO: Report full thread name if not an emu thread
-
- fmt::append(msg, "Thread id = %s.\n", std::this_thread::get_id());
+ append_thread_name(msg);
if (IsDebuggerPresent())
{
@@ -2542,8 +2544,7 @@ void thread_base::exec()
#endif
}
- // Assume main thread
- report_fatal_error(std::string(reason));
+ report_fatal_error(reason);
}
void thread_ctrl::detect_cpu_layout()
diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp
index ed0029530a..989d19c3f0 100644
--- a/rpcs3/Emu/System.cpp
+++ b/rpcs3/Emu/System.cpp
@@ -88,7 +88,7 @@ atomic_t g_progr_ptotal{0};
atomic_t g_progr_pdone{0};
// Report error and call std::abort(), defined in main.cpp
-[[noreturn]] void report_fatal_error(const std::string&);
+[[noreturn]] void report_fatal_error(std::string_view);
namespace
{
diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp
index 707d93ceb5..3cd1704caf 100644
--- a/rpcs3/main.cpp
+++ b/rpcs3/main.cpp
@@ -61,6 +61,8 @@ static atomic_t s_headless = false;
static atomic_t s_no_gui = false;
static atomic_t s_argv0;
+extern thread_local std::string(*g_tls_log_prefix)();
+
#ifndef _WIN32
extern char **environ;
#endif
@@ -68,15 +70,29 @@ extern char **environ;
LOG_CHANNEL(sys_log, "SYS");
LOG_CHANNEL(q_debug, "QDEBUG");
-[[noreturn]] extern void report_fatal_error(const std::string& text)
+[[noreturn]] extern void report_fatal_error(std::string_view _text)
{
+ std::string buf;
+
+ // Check if thread id is in string
+ if (_text.find("\nThread id = "sv) == umax)
+ {
+ // Copy only when needed
+ buf = std::string(_text);
+
+ // Always print thread id
+ fmt::append(buf, "\nThread id = %s.", std::this_thread::get_id());
+ }
+
+ const std::string_view text = buf.empty() ? _text : buf;
+
if (s_headless)
{
#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())
[[maybe_unused]] const auto con_out = freopen("conout$", "w", stderr);
#endif
- fprintf(stderr, "RPCS3: %s\n", text.c_str());
+ std::fprintf(stderr, "RPCS3: %.*s\n", static_cast(text.size()), text.data());
std::abort();
}
@@ -93,10 +109,10 @@ LOG_CHANNEL(q_debug, "QDEBUG");
}
else
{
- fprintf(stderr, "RPCS3: %s\n", text.c_str());
+ std::fprintf(stderr, "RPCS3: %.*s\n", static_cast(text.size()), text.data());
}
- auto show_report = [](const std::string& text)
+ auto show_report = [](std::string_view text)
{
fatal_error_dialog dlg(text);
dlg.exec();
@@ -154,7 +170,7 @@ LOG_CHANNEL(q_debug, "QDEBUG");
}
else
{
- fprintf(stderr, "posix_spawn() failed: %d\n", ret);
+ std::fprintf(stderr, "posix_spawn() failed: %d\n", ret);
}
#endif
std::abort();
diff --git a/rpcs3/rpcs3qt/fatal_error_dialog.cpp b/rpcs3/rpcs3qt/fatal_error_dialog.cpp
index becf5cfaed..497e634497 100644
--- a/rpcs3/rpcs3qt/fatal_error_dialog.cpp
+++ b/rpcs3/rpcs3qt/fatal_error_dialog.cpp
@@ -3,9 +3,7 @@
#include
#include
-#include
-
-fatal_error_dialog::fatal_error_dialog(const std::string& text) : QMessageBox()
+fatal_error_dialog::fatal_error_dialog(std::string_view text) : QMessageBox()
{
setWindowTitle(tr("RPCS3: Fatal Error"));
setIcon(QMessageBox::Icon::Critical);
@@ -18,7 +16,7 @@ fatal_error_dialog::fatal_error_dialog(const std::string& text) : QMessageBox()
%3
)")
- .arg(Qt::convertFromPlainText(QString::fromStdString(text)))
+ .arg(Qt::convertFromPlainText(QString::fromUtf8(text.data(), text.size())))
.arg(tr("HOW TO REPORT ERRORS:"))
.arg(tr("Please, don't send incorrect reports. Thanks for understanding.")));
layout()->setSizeConstraint(QLayout::SetFixedSize);
diff --git a/rpcs3/rpcs3qt/fatal_error_dialog.h b/rpcs3/rpcs3qt/fatal_error_dialog.h
index 15c5bbdc23..f7b4586c4e 100644
--- a/rpcs3/rpcs3qt/fatal_error_dialog.h
+++ b/rpcs3/rpcs3qt/fatal_error_dialog.h
@@ -2,12 +2,12 @@
#include
-#include
+#include
class fatal_error_dialog : public QMessageBox
{
Q_OBJECT
public:
- fatal_error_dialog(const std::string& text);
+ fatal_error_dialog(std::string_view text);
};
diff --git a/rpcs3/util/logs.cpp b/rpcs3/util/logs.cpp
index 72e83b5761..73ce17554c 100644
--- a/rpcs3/util/logs.cpp
+++ b/rpcs3/util/logs.cpp
@@ -2,6 +2,7 @@
#include "Utilities/File.h"
#include "Utilities/mutex.h"
#include "Utilities/Thread.h"
+#include "Utilities/StrFmt.h"
#include
#include
#include
@@ -25,13 +26,18 @@ using namespace std::literals::chrono_literals;
#include
-static std::string empty_string()
+static std::string default_string()
{
- return {};
+ if (thread_ctrl::is_main())
+ {
+ return {};
+ }
+
+ return fmt::format("TID: %s", std::this_thread::get_id());
}
// Thread-specific log prefix provider
-thread_local std::string(*g_tls_log_prefix)() = &empty_string;
+thread_local std::string(*g_tls_log_prefix)() = &default_string;
// Another thread-specific callback
thread_local void(*g_tls_log_control)(const char* fmt, u64 progress) = [](const char*, u64){};