From 444b5725b125e5154a571a1542cbb5a7ca58e29b Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 4 Jul 2020 20:07:20 +0200 Subject: Fix sanitizers (and tests) by allowing to specify which sanitizer to use. Its not possible to use all of them at the same time --- src/CmakeModule.cpp | 34 ++++++++++++++++++++++++++++++++-- src/main.cpp | 45 +++++++++++++++++++++++++++++++++------------ 2 files changed, 65 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp index a690948..f57a8cf 100644 --- a/src/CmakeModule.cpp +++ b/src/CmakeModule.cpp @@ -74,6 +74,23 @@ namespace sibs string allLinkerFlags = ""; #endif + if(config.getCompiler() == Compiler::GCC || config.getCompiler() == Compiler::MINGW_W64) + { + switch(config.getSanitize()) { + case Sanitize::NONE: + break; + case Sanitize::ADDRESS: + allLinkerFlags += " -lasan"; + break; + case Sanitize::UNDEFINED: + allLinkerFlags += TINYDIR_STRING(" -lubsan"); + break; + case Sanitize::LEAK: + allLinkerFlags += TINYDIR_STRING(" -llsan"); + break; + } + } + #if 0 // TODO: Somehow check loading order, because it has to be correct to work.. Or does it for dynamic libraries? // Anyways it's required for static libraries (especially on Windows) @@ -180,9 +197,22 @@ namespace sibs FileString cflags = TINYDIR_STRING("-fPIC"); FileString cxxflags; - if(config.getCompiler() == Compiler::GCC && config.getSanitize()) + if(config.getCompiler() == Compiler::GCC || config.getCompiler() == Compiler::MINGW_W64) { - cflags += TINYDIR_STRING(" -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -fsanitize=leak -lasan -lubsan -llsan"); + cflags += TINYDIR_STRING(" -fno-omit-frame-pointer"); + switch(config.getSanitize()) { + case Sanitize::NONE: + break; + case Sanitize::ADDRESS: + cflags += TINYDIR_STRING(" -fsanitize=address"); + break; + case Sanitize::UNDEFINED: + cflags += TINYDIR_STRING(" -fsanitize=undefined"); + break; + case Sanitize::LEAK: + cflags += TINYDIR_STRING(" -fsanitize=leak"); + break; + } } #if OS_FAMILY == OS_FAMILY_POSIX diff --git a/src/main.cpp b/src/main.cpp index 47da4bb..3d11fd5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -129,19 +129,19 @@ static void usage() static void usageBuild() { - printf("Usage: sibs build [project_path] [--debug|--release] [--sanitize] [--platform ]\n\n"); + printf("Usage: sibs build [project_path] [--debug|--release] [--sanitize=(address|undefined|leak|none)] [--platform ]\n\n"); printf("Build a sibs project\n\n"); printf("Options:\n"); printf(" project_path\t\tThe directory containing a project.conf file - Optional (default: current directory)\n"); printf(" --debug|--release\t\tOptimization level to build project and dependencies with (if not a system package) - Optional (default: --debug)\n"); - printf(" --sanitize\t\tAdd runtime address/undefined behavior sanitization. Program can be up to 3 times slower and use 10 times as much RAM. Ignored if compiler doesn't support sanitization - Optional (default: disabled)\n"); + printf(" --sanitize\t\tAdd runtime address/undefined behavior sanitization. Program can be up to 3 times slower and use 10 times as much RAM. Ignored if compiler doesn't support sanitization - Optional (default: none)\n"); printf(" --platform\t\tThe platform to build for - Optional (default: the running platform)\n"); printf("Examples:\n"); printf(" sibs build\n"); printf(" sibs build dirA/dirB\n"); printf(" sibs build --release\n"); printf(" sibs build dirA --release\n"); - printf(" sibs build --sanitize\n"); + printf(" sibs build --sanitize=address\n"); printf(" sibs build --release --platform win64\n"); exit(1); } @@ -163,17 +163,17 @@ static void usageNew() static void usageTest() { - printf("Usage: sibs test [project_path] [--no-sanitize] [--file ...|--all-files]\n\n"); + printf("Usage: sibs test [project_path] [--sanitize=(address|undefined|leak|none)] [--file ...|--all-files]\n\n"); printf("Build and run tests for a sibs project\n\n"); printf("Options:\n"); printf(" project_path\t\tThe directory containing a project.conf file - Optional (default: current directory)\n"); - printf(" --no-sanitize\t\tDisable runtime address/undefined behavior - Optional (default: enabled), Only applicable for C and C++\n"); + printf(" --sanitize\t\tAdd runtime address/undefined behavior sanitization. Program can be up to 3 times slower and use 10 times as much RAM. Ignored if compiler doesn't support sanitization - Optional (default: address)\n"); printf(" --file\t\t\tSpecify file to test, path to test file should be defined after this. Can be defined multiple times to test multiple files - Optional (default: not used), Only applicable for Zig\n"); printf(" --all-files\t\t\tTest all files - Optional (default: not used), Only applicable for Zig\n"); printf("Examples:\n"); printf(" sibs test\n"); printf(" sibs test dirA/dirB\n"); - printf(" sibs test --no-sanitize\n"); + printf(" sibs test --sanitize=none\n"); printf(" sibs test --all-files\n"); printf(" sibs test --file src/foo.zig --file src/bar.zig\n"); exit(1); @@ -450,11 +450,24 @@ static int buildProject(const FileString &projectPath, const FileString &project return 0; } +static Sanitize sanitize_string_to_type(const _tinydir_char_t *str) { + if(strcmp(str, TINYDIR_STRING("address")) == 0) + return Sanitize::ADDRESS; + else if(strcmp(str, TINYDIR_STRING("undefined")) == 0) + return Sanitize::UNDEFINED; + else if(strcmp(str, TINYDIR_STRING("leak")) == 0) + return Sanitize::LEAK; + else if(strcmp(str, TINYDIR_STRING("none")) == 0) + return Sanitize::NONE; + else + return SANITIZE_INVALID; +} + static int buildProject(int argc, const _tinydir_char_t **argv) { OptimizationLevel optimizationLevel = OPT_LEV_NONE; FileString projectPath; - bool sanitize = false; + Sanitize sanitize = Sanitize::NONE; FileString platformName; for(int i = 0; i < argc; ++i) @@ -478,9 +491,13 @@ static int buildProject(int argc, const _tinydir_char_t **argv) } optimizationLevel = OPT_LEV_RELEASE; } - else if(_tinydir_strcmp(arg, TINYDIR_STRING("--sanitize")) == 0) + else if(_tinydir_strncmp(arg, TINYDIR_STRING("--sanitize="), 10) == 0) { - sanitize = true; + sanitize = sanitize_string_to_type(arg + 11); + if(sanitize == SANITIZE_INVALID) { + ferr << "Error: Invalid sanitize option " << (arg + 11) << ", expected address, undefined, leak or none" << endl; + usageBuild(); + } } else if(_tinydir_strcmp(arg, TINYDIR_STRING("--platform")) == 0) { @@ -587,14 +604,18 @@ static int testProject(int argc, const _tinydir_char_t **argv) FileString projectPath; vector filesToTest; bool testAllFiles = false; - bool sanitize = true; + Sanitize sanitize = Sanitize::ADDRESS; for(int i = 0; i < argc; ++i) { const _tinydir_char_t *arg = argv[i]; - if(_tinydir_strcmp(arg, TINYDIR_STRING("--no-sanitize")) == 0) + if(_tinydir_strncmp(arg, TINYDIR_STRING("--sanitize="), 10) == 0) { - sanitize = false; + sanitize = sanitize_string_to_type(arg + 11); + if(sanitize == SANITIZE_INVALID) { + ferr << "Error: Invalid sanitize option " << (arg + 11) << ", expected address, undefined, leak or none" << endl; + usageTest(); + } } else if(_tinydir_strcmp(arg, TINYDIR_STRING("--file")) == 0) { -- cgit v1.2.3