Linux: Fix building without LTO (#9)

Fix building without LTO
Add support for debugging via ThreadSanitizer
This commit is contained in:
Eldred Habert 2023-02-19 01:19:10 +01:00 committed by GitHub
parent 39a7b8b254
commit 7473580da0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 37 deletions

View file

@ -37,18 +37,18 @@
#ifdef _MSC_VER
#define __noinline __declspec(noinline)
#endif
#ifndef __MINGW32__
#ifdef __clang__
#elif !defined(__MINGW32__) && (defined(__clang__) || defined(__GNUC__))
#define __noinline __attribute__((noinline))
// Some headers have functions marked as `__forceinline` but don't provide the bodies;
// it fails to compile when LTO is not enabled.
#ifdef HAVE_LTO
#define __forceinline __attribute__((always_inline)) inline
#define __noinline __attribute__((noinline))
#else
#ifdef __GNUC__
#define __forceinline __attribute__((always_inline)) inline
#define __noinline __attribute__((noinline))
#endif
#define __forceinline inline
#endif
#else
#define __forceinline inline
#define __noinline
#endif
using std::vector;
@ -70,4 +70,4 @@ using std::atomic_flag;
using std::atomic;
using std::thread;
using std::deque;
using std::optional;
using std::optional;

View file

@ -26,12 +26,10 @@ using std::atomic_flag;
using std::unordered_map;
using std::unordered_set;
#ifndef __MINGW32__
#ifdef __clang__
#define __forceinline __attribute__((always_inline)) inline
#else
#ifdef __GNUC__
#define __forceinline __attribute__((always_inline)) inline
#endif
#endif
#endif
// Some headers have functions marked as `__forceinline` but don't provide the bodies;
// it fails to compile when LTO is not enabled.
#if !defined(__MINGW32__) && (defined(__clang__) || defined(__GNUC__)) && defined(HAVE_LTO)
#define __forceinline __attribute__((always_inline)) inline
#else
#define __forceinline inline
#endif

1
linux-debugging/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
tsan.log.*

View file

@ -0,0 +1,18 @@
#!/usr/bin/gawk -f
BEGIN {
cmd = "llvm-symbolizer --output-style GNU -Ce bin/linux-x64/Release/MesenCore.so" addr
}
$4 ~ /MesenCore\.so/ {
match($4, /0x[0-9A-Fa-f]+/)
ofs = substr($4, RSTART, RLENGTH)
print ofs |& cmd
cmd |& getline func_name
cmd |& getline src
$2 = func_name
$3 = src
}
{ print }

View file

@ -0,0 +1,2 @@
called_from_lib:libcoreclr.so
called_from_lib:libclrjit.so

5
linux-debugging/tsan_launch.sh Executable file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$(realpath "$0")")"
TSAN_OPTIONS="suppressions=$PWD/suppressions log_path=$PWD/tsan.log" LD_PRELOAD=/usr/lib/libtsan.so ../bin/linux-x64/Release/linux-x64/publish/Mesen

View file

@ -21,8 +21,8 @@ endif
SDL2LIB := $(shell sdl2-config --libs)
SDL2INC := $(shell sdl2-config --cflags)
CXXFLAGS := -fPIC -Wall --std=c++17 $(MESENFLAGS) $(SDL2INC) -I $(realpath ./) -I $(realpath ./Core) -I $(realpath ./Utilities) -I $(realpath ./Linux)
CFLAGS := -fPIC -Wall $(MESENFLAGS)
CXXFLAGS = -fPIC -Wall --std=c++17 $(MESENFLAGS) $(SDL2INC) -I $(realpath ./) -I $(realpath ./Core) -I $(realpath ./Utilities) -I $(realpath ./Linux)
CFLAGS = -fPIC -Wall $(MESENFLAGS)
LINKCHECKUNRESOLVED := -Wl,-z,defs
@ -56,37 +56,40 @@ ifneq ($(filter arm%,$(MACHINE)),)
MESENPLATFORM := $(MESENOS)-arm64
endif
CXXFLAGS += -m64
CFLAGS += -m64
MESENFLAGS += -m64
ifeq ($(DEBUG),)
CFLAGS += -O3
CXXFLAGS += -O3
MESENFLAGS += -O3
ifneq ($(LTO),false)
CFLAGS += -flto
CXXFLAGS += -flto
MESENFLAGS += -flto -DHAVE_LTO
endif
else
CFLAGS += -O0 -g
CXXFLAGS += -O0 -g
MESENFLAGS += -O0 -g
# Note: if compiling with a sanitizer, you will likely need to `LD_PRELOAD` the library `libMesenCore.so` will be linked against.
ifeq ($(SANITIZER),address)
# Currently, `-fsanitize=address` is not supported together with `-fsanitize=thread`
ifneq ($(SANITIZER),)
ifeq ($(SANITIZER),address)
# Currently, `-fsanitize=address` is not supported together with `-fsanitize=thread`
MESENFLAGS += -fsanitize=address
else ifeq ($(SANITIZER),thread)
# Currently, `-fsanitize=address` is not supported together with `-fsanitize=thread`
MESENFLAGS += -fsanitize=thread
else
$(warning Unrecognised $$(SANITIZER) value: $(SANITIZER))
endif
# `-Wl,-z,defs` is incompatible with the sanitizers in a shared lib, unless the sanitizer libs are linked dynamically; hence `-shared-libsan` (not the default for Clang).
# It seems impossible to link dynamically against two sanitizers at the same time, but that might be a Clang limitation.
CFLAGS += -shared-libsan -fsanitize=address
CXXFLAGS += -shared-libsan -fsanitize=address
ifneq ($(USE_GCC),true)
MESENFLAGS += -shared-libsan
endif
endif
endif
ifeq ($(PGO),profile)
CFLAGS += ${PROFILE_GEN_FLAG}
CXXFLAGS += ${PROFILE_GEN_FLAG}
MESENFLAGS += ${PROFILE_GEN_FLAG}
endif
ifeq ($(PGO),optimize)
CFLAGS += ${PROFILE_USE_FLAG}
CXXFLAGS += ${PROFILE_USE_FLAG}
MESENFLAGS += ${PROFILE_USE_FLAG}
endif
ifneq ($(STATICLINK),false)