common: Move assert failure handling into a cpp file.
Advantage: Altering the handler does not need a full recompilation. Disadvantage: noreturn is droped, so the caller is a bit slower. We quite often run yuzu with a YOLO assertion handler. In fact, only very few games run at all with asserts. This patch allows developers to patch the handler without recompiling everything. The overhead of the missing "noreturn" attribute shoul be negletable.
This commit is contained in:
parent
69b2dbdffd
commit
9be819faaf
@ -97,6 +97,7 @@ add_custom_command(OUTPUT scm_rev.cpp
|
|||||||
add_library(common STATIC
|
add_library(common STATIC
|
||||||
algorithm.h
|
algorithm.h
|
||||||
alignment.h
|
alignment.h
|
||||||
|
assert.cpp
|
||||||
assert.h
|
assert.h
|
||||||
atomic_ops.h
|
atomic_ops.h
|
||||||
detached_tasks.cpp
|
detached_tasks.cpp
|
||||||
|
11
src/common/assert.cpp
Normal file
11
src/common/assert.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
|
||||||
|
void assert_handle_failure() {
|
||||||
|
Crash();
|
||||||
|
}
|
@ -4,10 +4,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include "common/common_funcs.h"
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
|
||||||
|
// Sometimes we want to try to continue even after hitting an assert.
|
||||||
|
// However touching this file yields a global recompilation as this header is included almost
|
||||||
|
// everywhere. So let's just move the handling of the failed assert to a single cpp file.
|
||||||
|
void assert_handle_failure();
|
||||||
|
|
||||||
// For asserts we'd like to keep all the junk executed when an assert happens away from the
|
// For asserts we'd like to keep all the junk executed when an assert happens away from the
|
||||||
// important code in the function. One way of doing this is to put all the relevant code inside a
|
// important code in the function. One way of doing this is to put all the relevant code inside a
|
||||||
// lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to
|
// lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to
|
||||||
@ -17,15 +20,14 @@
|
|||||||
// enough for our purposes.
|
// enough for our purposes.
|
||||||
template <typename Fn>
|
template <typename Fn>
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
[[msvc::noinline, noreturn]]
|
[[msvc::noinline]]
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
[[gnu::cold, gnu::noinline, noreturn]]
|
[[gnu::cold, gnu::noinline]]
|
||||||
#endif
|
#endif
|
||||||
static void
|
static void
|
||||||
assert_noinline_call(const Fn& fn) {
|
assert_noinline_call(const Fn& fn) {
|
||||||
fn();
|
fn();
|
||||||
Crash();
|
assert_handle_failure();
|
||||||
exit(1); // Keeps GCC's mouth shut about this actually returning
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ASSERT(_a_) \
|
#define ASSERT(_a_) \
|
||||||
|
Loading…
Reference in New Issue
Block a user