Index: projects/compiler-rt/lib/scudo/scudo_allocator.cpp =================================================================== --- projects/compiler-rt/lib/scudo/scudo_allocator.cpp +++ projects/compiler-rt/lib/scudo/scudo_allocator.cpp @@ -76,7 +76,7 @@ u64 Offset : 20; // Offset from the beginning of the backend // allocation to the beginning chunk itself, in // multiples of MinAlignment. See comment about its - // maximum value and test in Initialize. + // maximum value and test in init(). u64 Unused_1_ : 28; u16 Salt : 16; }; Index: projects/compiler-rt/lib/scudo/scudo_flags.cpp =================================================================== --- projects/compiler-rt/lib/scudo/scudo_flags.cpp +++ projects/compiler-rt/lib/scudo/scudo_flags.cpp @@ -17,9 +17,12 @@ #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_flag_parser.h" +extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE +const char* getScudoDefaultOptions(); + namespace __scudo { -Flags scudo_flags_dont_use_directly; // use via flags(). +Flags ScudoFlags; // Use via getFlags(). void Flags::setDefaults() { #define SCUDO_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; @@ -34,6 +37,10 @@ #undef SCUDO_FLAG } +static const char *callGetScudoDefaultOptions() { + return (&getScudoDefaultOptions) ? getScudoDefaultOptions() : ""; +} + void initFlags() { SetCommonFlagsDefaults(); { @@ -45,11 +52,16 @@ Flags *f = getFlags(); f->setDefaults(); - FlagParser scudo_parser; - RegisterScudoFlags(&scudo_parser, f); - RegisterCommonFlags(&scudo_parser); + FlagParser ScudoParser; + RegisterScudoFlags(&ScudoParser, f); + RegisterCommonFlags(&ScudoParser); + + // Override from user-specified string. + const char *ScudoDefaultOptions = callGetScudoDefaultOptions(); + ScudoParser.ParseString(ScudoDefaultOptions); - scudo_parser.ParseString(GetEnv("SCUDO_OPTIONS")); + // Override from environment. + ScudoParser.ParseString(GetEnv("SCUDO_OPTIONS")); InitializeCommonFlags(); @@ -75,7 +87,7 @@ } Flags *getFlags() { - return &scudo_flags_dont_use_directly; + return &ScudoFlags; } } Index: projects/compiler-rt/test/scudo/options.cpp =================================================================== --- projects/compiler-rt/test/scudo/options.cpp +++ projects/compiler-rt/test/scudo/options.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_scudo %s -o %t +// RUN: %run %t 2>&1 +// RUN: SCUDO_OPTIONS=DeallocationTypeMismatch=0 %run %t 2>&1 +// RUN: SCUDO_OPTIONS=DeallocationTypeMismatch=1 not %run %t 2>&1 | FileCheck %s + +// Tests that the options can be passed using getScudoDefaultOptions, and that +// the environment ones take precedence over them. + +#include +#include + +extern "C" const char* getScudoDefaultOptions() { + return "DeallocationTypeMismatch=0"; // Defaults to true in scudo_flags.inc. +} + +int main(int argc, char **argv) +{ + int *p = (int *)malloc(16); + if (!p) + return 1; + delete p; + return 0; +} + +// CHECK: ERROR: allocation type mismatch on address