Disable exception handling.

Use -fno-exceptions in cmake.
On MSVC, enable _HAS_EXCEPTION=0.
Cleanup throw/catch from the source.
Create yaml.cpp enclave because it needs exception to work.
Disable thread_local optimizations in logs.cpp (TODO).
Implement cpu_counter for cpu_threads (moved globals).
This commit is contained in:
Nekotekina 2020-03-09 19:18:39 +03:00
parent 47bbfdd2aa
commit 04dedb17eb
39 changed files with 421 additions and 437 deletions

View file

@ -1,11 +1,14 @@
#include "stdafx.h"
#include "Config.h"
#include "Utilities/types.h"
#include "yaml-cpp/yaml.h"
#include "util/yaml.hpp"
#include <typeinfo>
#include <charconv>
[[noreturn]] void report_fatal_error(const std::string&);
LOG_CHANNEL(cfg_log, "CFG");
namespace cfg
@ -15,7 +18,7 @@ namespace cfg
{
if (_type != type::node)
{
fmt::throw_exception("Invalid root node" HERE);
cfg_log.fatal("Invalid root node" HERE);
}
}
@ -26,7 +29,7 @@ namespace cfg
{
if (pair.first == name)
{
fmt::throw_exception("Node already exists: %s" HERE, name);
cfg_log.fatal("Node already exists: %s" HERE, name);
}
}
@ -35,12 +38,12 @@ namespace cfg
bool _base::from_string(const std::string&, bool)
{
fmt::throw_exception("from_string() purecall" HERE);
report_fatal_error("from_string() purecall" HERE);
}
bool _base::from_list(std::vector<std::string>&&)
{
fmt::throw_exception("from_list() purecall" HERE);
report_fatal_error("from_list() purecall" HERE);
}
// Emit YAML
@ -302,14 +305,17 @@ std::string cfg::node::to_string() const
return {out.c_str(), out.size()};
}
bool cfg::node::from_string(const std::string& value, bool dynamic) try
bool cfg::node::from_string(const std::string& value, bool dynamic)
{
cfg::decode(YAML::Load(value), *this, dynamic);
return true;
}
catch (const std::exception& e)
{
cfg_log.fatal("%s thrown: %s", typeid(e).name(), e.what());
auto [result, error] = yaml_load(value);
if (error.empty())
{
cfg::decode(result, *this, dynamic);
return true;
}
cfg_log.fatal("Failed to load node: %s", error);
return false;
}

View file

@ -60,22 +60,6 @@ void fmt_class_string<std::thread::id>::format(std::string& out, u64 arg)
out += ss.str();
}
[[noreturn]] void catch_all_exceptions()
{
try
{
throw;
}
catch (const std::exception& e)
{
report_fatal_error("{" + g_tls_log_prefix() + "} Unhandled exception of type '"s + typeid(e).name() + "': "s + e.what());
}
catch (...)
{
report_fatal_error("{" + g_tls_log_prefix() + "} Unhandled exception (unknown)");
}
}
#ifndef _WIN32
bool IsDebuggerPresent()
{
@ -1151,33 +1135,12 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) no
if (rsx::g_access_violation_handler)
{
bool handled = false;
try
if (cpu)
{
if (cpu)
{
vm::temporary_unlock(*cpu);
}
handled = rsx::g_access_violation_handler(addr, is_writing);
vm::temporary_unlock(*cpu);
}
catch (const std::exception& e)
{
rsx_log.fatal("g_access_violation_handler(0x%x, %d): %s", addr, is_writing, e.what());
if (cpu)
{
cpu->state += cpu_flag::dbg_pause;
if (cpu->test_stopped())
{
std::terminate();
}
}
return false;
}
bool handled = rsx::g_access_violation_handler(addr, is_writing);
if (handled)
{
@ -1769,7 +1732,7 @@ const bool s_exception_handler_set = []() -> bool
if (::sigaction(SIGSEGV, &sa, NULL) == -1)
{
std::fprintf(stderr, "sigaction(SIGSEGV) failed (0x%x).", errno);
std::fprintf(stderr, "sigaction(SIGSEGV) failed (%d).\n", errno);
std::abort();
}
@ -1779,6 +1742,23 @@ const bool s_exception_handler_set = []() -> bool
#endif
const bool s_terminate_handler_set = []() -> bool
{
std::set_terminate([]()
{
if (IsDebuggerPresent())
#ifdef _MSC_VER
__debugbreak();
#else
__asm("int3;");
#endif
report_fatal_error("RPCS3 has abnormally terminated.");
});
return true;
}();
thread_local DECLARE(thread_ctrl::g_tls_this_thread) = nullptr;
DECLARE(thread_ctrl::g_native_core_layout) { native_core_arrangement::undefined };

View file

@ -15,9 +15,6 @@
// 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();
// Hardware core layout
enum class native_core_arrangement : u32
{
@ -256,9 +253,9 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
// Type-erased thread entry point
#ifdef _WIN32
static inline uint __stdcall entry_point(void* arg) try
static inline uint __stdcall entry_point(void* arg)
#else
static inline void* entry_point(void* arg) try
static inline void* entry_point(void* arg)
#endif
{
const auto _this = static_cast<named_thread*>(static_cast<thread*>(arg));
@ -272,10 +269,6 @@ class named_thread final : public Context, result_storage_t<Context>, thread_bas
thread::finalize();
return 0;
}
catch (...)
{
catch_all_exceptions();
}
bool entry_point()
{

View file

@ -1,5 +1,5 @@
#include "bin_patch.h"
#include <yaml-cpp/yaml.h>
#include "util/yaml.hpp"
#include "File.h"
#include "Config.h"
@ -34,15 +34,11 @@ void patch_engine::append(const std::string& patch)
{
if (fs::file f{patch})
{
YAML::Node root;
auto [root, error] = yaml_load(f.to_string());
try
if (!error.empty())
{
root = YAML::Load(f.to_string());
}
catch (const std::exception& e)
{
patch_log.fatal("Failed to load patch file %s\n%s thrown: %s", patch, typeid(e).name(), e.what());
patch_log.fatal("Failed to load patch file %s:\n%s", patch, error);
return;
}