Posix/Linux: Add setting to disable coredumps

This commit is contained in:
goeiecool9999 2022-09-27 13:58:50 +02:00 committed by GitHub
parent 35afb99c99
commit 6ecc4be0da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 22 deletions

View File

@ -1,36 +1,73 @@
#include <signal.h> #include <signal.h>
#include <execinfo.h> #include <execinfo.h>
#include <string.h>
void handler_SIGSEGV(int sig) #include "config/CemuConfig.h"
// handle signals that would dump core, print stacktrace and then dump depending on config
void handlerDumpingSignal(int sig)
{ {
printf("SIGSEGV!\n"); char* sigName = strsignal(sig);
if (sigName)
{
printf("%s!\n", sigName);
}
else
{
// should never be the case
printf("Unknown core dumping signal!\n");
}
void *array[32]; void *array[32];
size_t size; size_t size;
// get void*'s for all entries on the stack // get void*'s for all entries on the stack
size = backtrace(array, 32); size = backtrace(array, 32);
// print out all the frames to stderr // print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig); fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO); backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
if (GetConfig().crash_dump == CrashDump::Enabled)
{
// reset signal handler to default and re-raise signal to dump core
signal(sig, SIG_DFL);
raise(sig);
return;
}
// exit process ignoring all issues
_Exit(1);
} }
void handler_SIGINT(int sig) void handler_SIGINT(int sig)
{ {
/* /*
* Received when pressing CTRL + C in a console * Received when pressing CTRL + C in a console
* Ideally should be exiting cleanly after saving settings but currently * Ideally should be exiting cleanly after saving settings but currently
* there's no clean exit pathway (at least on linux) and exiting the app * there's no clean exit pathway (at least on linux) and exiting the app
* by any mean ends up with a SIGABRT from the standard library destroying * by any mean ends up with a SIGABRT from the standard library destroying
* threads. * threads.
*/ */
_Exit(0); _Exit(0);
} }
void ExceptionHandler_init() void ExceptionHandler_init()
{ {
signal(SIGSEGV, handler_SIGSEGV); struct sigaction action;
signal(SIGINT, handler_SIGINT); action.sa_flags = 0;
sigfillset(&action.sa_mask); // don't allow signals to be interrupted
action.sa_handler = handler_SIGINT;
sigaction(SIGINT, &action, nullptr);
action.sa_handler = handlerDumpingSignal;
sigaction(SIGABRT, &action, nullptr);
sigaction(SIGBUS, &action, nullptr);
sigaction(SIGFPE, &action, nullptr);
sigaction(SIGILL, &action, nullptr);
sigaction(SIGIOT, &action, nullptr);
sigaction(SIGQUIT, &action, nullptr);
sigaction(SIGSEGV, &action, nullptr);
sigaction(SIGSYS, &action, nullptr);
sigaction(SIGTRAP, &action, nullptr);
} }

View File

@ -316,7 +316,11 @@ void CemuConfig::Load(XMLConfigParser& parser)
// debug // debug
auto debug = parser.get("Debug"); auto debug = parser.get("Debug");
crash_dump = debug.get("CrashDump", crash_dump); #if BOOST_OS_WINDOWS
crash_dump = debug.get("CrashDumpWindows", crash_dump);
#elif BOOST_OS_UNIX
crash_dump = debug.get("CrashDumpUnix", crash_dump);
#endif
// input // input
auto input = parser.get("Input"); auto input = parser.get("Input");
@ -487,7 +491,11 @@ void CemuConfig::Save(XMLConfigParser& parser)
// debug // debug
auto debug = config.set("Debug"); auto debug = config.set("Debug");
debug.set("CrashDump", crash_dump.GetValue()); #if BOOST_OS_WINDOWS
debug.set("CrashDumpWindows", crash_dump.GetValue());
#elif BOOST_OS_UNIX
debug.set("CrashDumpUnix", crash_dump.GetValue());
#endif
// input // input
auto input = config.set("Input"); auto input = config.set("Input");

View File

@ -172,6 +172,7 @@ enum class CafeConsoleLanguage
}; };
ENABLE_ENUM_ITERATORS(CafeConsoleLanguage, CafeConsoleLanguage::JA, CafeConsoleLanguage::TW); ENABLE_ENUM_ITERATORS(CafeConsoleLanguage, CafeConsoleLanguage::JA, CafeConsoleLanguage::TW);
#if BOOST_OS_WINDOWS
enum class CrashDump enum class CrashDump
{ {
Disabled, Disabled,
@ -179,6 +180,14 @@ enum class CrashDump
Full Full
}; };
ENABLE_ENUM_ITERATORS(CrashDump, CrashDump::Disabled, CrashDump::Full); ENABLE_ENUM_ITERATORS(CrashDump, CrashDump::Disabled, CrashDump::Full);
#elif BOOST_OS_UNIX
enum class CrashDump
{
Disabled,
Enabled
};
ENABLE_ENUM_ITERATORS(CrashDump, CrashDump::Disabled, CrashDump::Enabled);
#endif
template <> template <>
struct fmt::formatter<PrecompiledShaderOption> : formatter<string_view> { struct fmt::formatter<PrecompiledShaderOption> : formatter<string_view> {
@ -290,6 +299,7 @@ struct fmt::formatter<CafeConsoleLanguage> : formatter<string_view> {
} }
}; };
#if BOOST_OS_WINDOWS
template <> template <>
struct fmt::formatter<CrashDump> : formatter<string_view> { struct fmt::formatter<CrashDump> : formatter<string_view> {
template <typename FormatContext> template <typename FormatContext>
@ -306,6 +316,23 @@ struct fmt::formatter<CrashDump> : formatter<string_view> {
return formatter<string_view>::format(name, ctx); return formatter<string_view>::format(name, ctx);
} }
}; };
#elif BOOST_OS_UNIX
template <>
struct fmt::formatter<CrashDump> : formatter<string_view> {
template <typename FormatContext>
auto format(const CrashDump v, FormatContext &ctx) {
string_view name;
switch (v)
{
case CrashDump::Disabled: name = "Disabled"; break;
case CrashDump::Enabled: name = "Enabled"; break;
default: name = "unknown"; break;
}
return formatter<string_view>::format(name, ctx);
}
};
#endif
struct CemuConfig struct CemuConfig

View File

@ -709,10 +709,18 @@ wxPanel* GeneralSettings2::AddDebugPage(wxNotebook* notebook)
debug_row->Add(new wxStaticText(panel, wxID_ANY, _("Crash dump"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); debug_row->Add(new wxStaticText(panel, wxID_ANY, _("Crash dump"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
#if BOOST_OS_WINDOWS
wxString dump_choices[] = { _("Disabled"), _("Lite"), _("Full") }; wxString dump_choices[] = { _("Disabled"), _("Lite"), _("Full") };
#elif BOOST_OS_UNIX
wxString dump_choices[] = { _("Disabled"), _("Enabled") };
#endif
m_crash_dump = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, std::size(dump_choices), dump_choices); m_crash_dump = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, std::size(dump_choices), dump_choices);
m_crash_dump->SetSelection(0); m_crash_dump->SetSelection(0);
#if BOOST_OS_WINDOWS
m_crash_dump->SetToolTip(_("Creates a dump when Cemu crashes\nOnly enable when requested by a developer!\nThe Full option will create a very large dump file (includes a full RAM dump of the Cemu process)")); m_crash_dump->SetToolTip(_("Creates a dump when Cemu crashes\nOnly enable when requested by a developer!\nThe Full option will create a very large dump file (includes a full RAM dump of the Cemu process)"));
#elif BOOST_OS_UNIX
m_crash_dump->SetToolTip(_("Creates a core dump when Cemu crashes\nOnly enable when requested by a developer!"));
#endif
debug_row->Add(m_crash_dump, 0, wxALL | wxEXPAND, 5); debug_row->Add(m_crash_dump, 0, wxALL | wxEXPAND, 5);
debug_panel_sizer->Add(debug_row, 0, wxALL | wxEXPAND, 5); debug_panel_sizer->Add(debug_row, 0, wxALL | wxEXPAND, 5);