mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
Add information about unnamed/main threads in logs and fatal dialog
* If thread is unnamed, keep log name empty for main thread, otherwise print thread id. In fatal dialog, main thread can be handled differently (with special remark that it's main thread). * Always print thread id in fatal dialog, regardless of thread type. Co-authored-by: Nekotekina <nekotekina@gmail.com>
This commit is contained in:
parent
40f3adc45f
commit
cd6ef2958b
@ -94,7 +94,7 @@ thread_local bool g_tls_access_violation_recovered = false;
|
|||||||
extern thread_local std::string(*g_tls_log_prefix)();
|
extern thread_local std::string(*g_tls_log_prefix)();
|
||||||
|
|
||||||
// Report error and call std::abort(), defined in main.cpp
|
// 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 <>
|
template <>
|
||||||
void fmt_class_string<std::thread::id>::format(std::string& out, u64 arg)
|
void fmt_class_string<std::thread::id>::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;
|
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
|
#ifdef _WIN32
|
||||||
|
|
||||||
static LONG exception_handler(PEXCEPTION_POINTERS pExp) noexcept
|
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())
|
append_thread_name(msg);
|
||||||
{
|
|
||||||
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());
|
|
||||||
|
|
||||||
std::vector<HMODULE> modules;
|
std::vector<HMODULE> modules;
|
||||||
for (DWORD size = 256; modules.size() != size; size /= sizeof(HMODULE))
|
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));
|
std::string msg = fmt::format("Segfault %s location %p at %p.\n", cause, info->si_addr, RIP(context));
|
||||||
|
|
||||||
if (thread_ctrl::get_current())
|
append_thread_name(msg);
|
||||||
{
|
|
||||||
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());
|
|
||||||
|
|
||||||
if (IsDebuggerPresent())
|
if (IsDebuggerPresent())
|
||||||
{
|
{
|
||||||
@ -2542,8 +2544,7 @@ void thread_base::exec()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume main thread
|
report_fatal_error(reason);
|
||||||
report_fatal_error(std::string(reason));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_ctrl::detect_cpu_layout()
|
void thread_ctrl::detect_cpu_layout()
|
||||||
|
@ -88,7 +88,7 @@ atomic_t<u32> g_progr_ptotal{0};
|
|||||||
atomic_t<u32> g_progr_pdone{0};
|
atomic_t<u32> g_progr_pdone{0};
|
||||||
|
|
||||||
// Report error and call std::abort(), defined in main.cpp
|
// 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
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -61,6 +61,8 @@ static atomic_t<bool> s_headless = false;
|
|||||||
static atomic_t<bool> s_no_gui = false;
|
static atomic_t<bool> s_no_gui = false;
|
||||||
static atomic_t<char*> s_argv0;
|
static atomic_t<char*> s_argv0;
|
||||||
|
|
||||||
|
extern thread_local std::string(*g_tls_log_prefix)();
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
#endif
|
#endif
|
||||||
@ -68,15 +70,29 @@ extern char **environ;
|
|||||||
LOG_CHANNEL(sys_log, "SYS");
|
LOG_CHANNEL(sys_log, "SYS");
|
||||||
LOG_CHANNEL(q_debug, "QDEBUG");
|
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)
|
if (s_headless)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())
|
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole())
|
||||||
[[maybe_unused]] const auto con_out = freopen("conout$", "w", stderr);
|
[[maybe_unused]] const auto con_out = freopen("conout$", "w", stderr);
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "RPCS3: %s\n", text.c_str());
|
std::fprintf(stderr, "RPCS3: %.*s\n", static_cast<int>(text.size()), text.data());
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,10 +109,10 @@ LOG_CHANNEL(q_debug, "QDEBUG");
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "RPCS3: %s\n", text.c_str());
|
std::fprintf(stderr, "RPCS3: %.*s\n", static_cast<int>(text.size()), text.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto show_report = [](const std::string& text)
|
auto show_report = [](std::string_view text)
|
||||||
{
|
{
|
||||||
fatal_error_dialog dlg(text);
|
fatal_error_dialog dlg(text);
|
||||||
dlg.exec();
|
dlg.exec();
|
||||||
@ -154,7 +170,7 @@ LOG_CHANNEL(q_debug, "QDEBUG");
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "posix_spawn() failed: %d\n", ret);
|
std::fprintf(stderr, "posix_spawn() failed: %d\n", ret);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
std::abort();
|
std::abort();
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
|
|
||||||
#include <string>
|
fatal_error_dialog::fatal_error_dialog(std::string_view text) : QMessageBox()
|
||||||
|
|
||||||
fatal_error_dialog::fatal_error_dialog(const std::string& text) : QMessageBox()
|
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("RPCS3: Fatal Error"));
|
setWindowTitle(tr("RPCS3: Fatal Error"));
|
||||||
setIcon(QMessageBox::Icon::Critical);
|
setIcon(QMessageBox::Icon::Critical);
|
||||||
@ -18,7 +16,7 @@ fatal_error_dialog::fatal_error_dialog(const std::string& text) : QMessageBox()
|
|||||||
%3<br>
|
%3<br>
|
||||||
</p>
|
</p>
|
||||||
)")
|
)")
|
||||||
.arg(Qt::convertFromPlainText(QString::fromStdString(text)))
|
.arg(Qt::convertFromPlainText(QString::fromUtf8(text.data(), text.size())))
|
||||||
.arg(tr("HOW TO REPORT ERRORS:"))
|
.arg(tr("HOW TO REPORT ERRORS:"))
|
||||||
.arg(tr("Please, don't send incorrect reports. Thanks for understanding.")));
|
.arg(tr("Please, don't send incorrect reports. Thanks for understanding.")));
|
||||||
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include <string>
|
#include <string_view>
|
||||||
|
|
||||||
class fatal_error_dialog : public QMessageBox
|
class fatal_error_dialog : public QMessageBox
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fatal_error_dialog(const std::string& text);
|
fatal_error_dialog(std::string_view text);
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "Utilities/File.h"
|
#include "Utilities/File.h"
|
||||||
#include "Utilities/mutex.h"
|
#include "Utilities/mutex.h"
|
||||||
#include "Utilities/Thread.h"
|
#include "Utilities/Thread.h"
|
||||||
|
#include "Utilities/StrFmt.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -25,13 +26,18 @@ using namespace std::literals::chrono_literals;
|
|||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
static std::string empty_string()
|
static std::string default_string()
|
||||||
{
|
{
|
||||||
|
if (thread_ctrl::is_main())
|
||||||
|
{
|
||||||
return {};
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt::format("TID: %s", std::this_thread::get_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thread-specific log prefix provider
|
// 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
|
// Another thread-specific callback
|
||||||
thread_local void(*g_tls_log_control)(const char* fmt, u64 progress) = [](const char*, u64){};
|
thread_local void(*g_tls_log_control)(const char* fmt, u64 progress) = [](const char*, u64){};
|
||||||
|
Loading…
Reference in New Issue
Block a user