diff --git a/Source/Engine/Core/Compiler.h b/Source/Engine/Core/Compiler.h index 66a411a1d..3eebd5393 100644 --- a/Source/Engine/Core/Compiler.h +++ b/Source/Engine/Core/Compiler.h @@ -14,6 +14,7 @@ #define FORCE_INLINE inline #define FORCE_NOINLINE __attribute__((noinline)) #define NO_RETURN __attribute__((noreturn)) +#define NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) #define PACK_BEGIN() #define PACK_END() __attribute__((__packed__)) #define ALIGN_BEGIN(_align) @@ -44,6 +45,7 @@ #define FORCE_INLINE inline #define FORCE_NOINLINE __attribute__((noinline)) #define NO_RETURN __attribute__((noreturn)) +#define NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) #define PACK_BEGIN() #define PACK_END() __attribute__((__packed__)) #define ALIGN_BEGIN(_align) @@ -69,6 +71,7 @@ #define FORCE_INLINE __forceinline #define FORCE_NOINLINE __declspec(noinline) #define NO_RETURN __declspec(noreturn) +#define NO_SANITIZE_ADDRESS #define PACK_BEGIN() __pragma(pack(push, 1)) #define PACK_END() ; __pragma(pack(pop)) #define ALIGN_BEGIN(_align) __declspec(align(_align)) diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/CompileEnvironment.cs b/Source/Tools/Flax.Build/Build/NativeCpp/CompileEnvironment.cs index d9271e586..8b1d461c1 100644 --- a/Source/Tools/Flax.Build/Build/NativeCpp/CompileEnvironment.cs +++ b/Source/Tools/Flax.Build/Build/NativeCpp/CompileEnvironment.cs @@ -26,6 +26,28 @@ namespace Flax.Build.NativeCpp SmallCode } + /// + /// The code sanitizers for core errors detection by compiler-supported checks. + /// + [Flags] + public enum Sanitizer + { + /// + /// No sanitizers in use. + /// + None = 0, + + /// + /// Memory errors detector, + /// + Address = 1, + + /// + /// Data races and deadlocks detector. + /// + Thread = 2, + } + /// /// The compilation optimization hint. /// @@ -67,6 +89,11 @@ namespace Flax.Build.NativeCpp /// public FavorSizeOrSpeed FavorSizeOrSpeed = FavorSizeOrSpeed.Neither; + /// + /// Selects a sanitizers to use (as flags). + /// + public Sanitizer Sanitizers = Sanitizer.None; + /// /// Enables exceptions support. /// @@ -184,6 +211,7 @@ namespace Flax.Build.NativeCpp { CppVersion = CppVersion, FavorSizeOrSpeed = FavorSizeOrSpeed, + Sanitizers = Sanitizers, EnableExceptions = EnableExceptions, RuntimeTypeInfo = RuntimeTypeInfo, Inlining = Inlining, diff --git a/Source/Tools/Flax.Build/Build/Target.cs b/Source/Tools/Flax.Build/Build/Target.cs index 5820d14d6..90523b5ef 100644 --- a/Source/Tools/Flax.Build/Build/Target.cs +++ b/Source/Tools/Flax.Build/Build/Target.cs @@ -249,6 +249,7 @@ namespace Flax.Build } options.CompileEnv.EnableExceptions = true; // TODO: try to disable this! + options.CompileEnv.Sanitizers = Configuration.Sanitizers; switch (options.Configuration) { case TargetConfiguration.Debug: diff --git a/Source/Tools/Flax.Build/Build/Toolchain.cs b/Source/Tools/Flax.Build/Build/Toolchain.cs index 6d90dc850..553e80032 100644 --- a/Source/Tools/Flax.Build/Build/Toolchain.cs +++ b/Source/Tools/Flax.Build/Build/Toolchain.cs @@ -182,5 +182,18 @@ namespace Flax.Build } return true; } + + /// + /// Utility that outputs the arguments for Clang with specific sanitizer. + /// + /// The sanitizers as flags. + /// The arguments list. + protected void AddClangSanitizerArgs(Sanitizer sanitizers, List args) + { + if (sanitizers.HasFlag(Sanitizer.Address)) + args.Add("-fsanitize=address"); + if (sanitizers.HasFlag(Sanitizer.Thread)) + args.Add("-fsanitize=thread"); + } } } diff --git a/Source/Tools/Flax.Build/Configuration.cs b/Source/Tools/Flax.Build/Configuration.cs index 8c12fc207..63d4aa5b3 100644 --- a/Source/Tools/Flax.Build/Configuration.cs +++ b/Source/Tools/Flax.Build/Configuration.cs @@ -225,6 +225,12 @@ namespace Flax.Build [CommandLine("compiler", "", "Overrides the compiler to use for building. Eg. v140 overrides the toolset when building for Windows.")] public static string Compiler = null; + /// + /// Selects a sanitizers to use (as flags). Options: Address, Thread. + /// + [CommandLine("sanitizers", "", "Selects a sanitizers to use (as flags). Options: Address, Thread.")] + public static Flax.Build.NativeCpp.Sanitizer Sanitizers = Flax.Build.NativeCpp.Sanitizer.None; + /// /// Specifies the dotnet SDK version to use for the build. Eg. set to '7' to use .NET 7 even if .NET 8 is installed. /// @@ -242,6 +248,8 @@ namespace Flax.Build cmdLine += " -compiler=" + Compiler; if (!string.IsNullOrEmpty(Dotnet)) cmdLine += " -dotnet=" + Dotnet; + if (Sanitizers != Flax.Build.NativeCpp.Sanitizer.None) + cmdLine += " -sanitizers=" + Sanitizers.ToString(); } } diff --git a/Source/Tools/Flax.Build/Platforms/Apple/AppleToolchain.cs b/Source/Tools/Flax.Build/Platforms/Apple/AppleToolchain.cs index a1268ddfc..c3c96b035 100644 --- a/Source/Tools/Flax.Build/Platforms/Apple/AppleToolchain.cs +++ b/Source/Tools/Flax.Build/Platforms/Apple/AppleToolchain.cs @@ -105,6 +105,7 @@ namespace Flax.Build.Platforms commonArgs.Add("objective-c++"); commonArgs.Add("-stdlib=libc++"); AddArgsCommon(options, commonArgs); + AddClangSanitizerArgs(compileEnvironment.Sanitizers, commonArgs); switch (compileEnvironment.CppVersion) { @@ -155,14 +156,24 @@ namespace Flax.Build.Platforms commonArgs.Add("-pthread"); - if (compileEnvironment.FavorSizeOrSpeed == FavorSizeOrSpeed.FastCode) - commonArgs.Add("-Ofast"); - else if (compileEnvironment.FavorSizeOrSpeed == FavorSizeOrSpeed.SmallCode) - commonArgs.Add("-Os"); - if (compileEnvironment.Optimization) - commonArgs.Add("-O3"); + if (compileEnvironment.Sanitizers.HasFlag(Sanitizer.Address)) + { + commonArgs.Add("-fno-optimize-sibling-calls"); + commonArgs.Add("-fno-omit-frame-pointer"); + if (compileEnvironment.Optimization) + commonArgs.Add("-O1"); + } else - commonArgs.Add("-O0"); + { + if (compileEnvironment.FavorSizeOrSpeed == FavorSizeOrSpeed.FastCode) + commonArgs.Add("-Ofast"); + else if (compileEnvironment.FavorSizeOrSpeed == FavorSizeOrSpeed.SmallCode) + commonArgs.Add("-Os"); + if (compileEnvironment.Optimization) + commonArgs.Add("-O3"); + else + commonArgs.Add("-O0"); + } if (compileEnvironment.BufferSecurityCheck) commonArgs.Add("-fstack-protector"); @@ -240,6 +251,7 @@ namespace Flax.Build.Platforms { args.Add(string.Format("-o \"{0}\"", outputFilePath)); AddArgsCommon(options, args); + AddClangSanitizerArgs(options.CompileEnv.Sanitizers, args); if (isArchive) {