1 //===-- sanitizer_flags_test.cc -------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 11 // 12 //===----------------------------------------------------------------------===// 13 #include "sanitizer_common/sanitizer_common.h" 14 #include "sanitizer_common/sanitizer_flags.h" 15 #include "sanitizer_common/sanitizer_flag_parser.h" 16 #include "sanitizer_common/sanitizer_libc.h" 17 #include "sanitizer_common/sanitizer_allocator_internal.h" 18 #include "gtest/gtest.h" 19 20 #include <string.h> 21 22 namespace __sanitizer { 23 24 static const char kFlagName[] = "flag_name"; 25 static const char kFlagDesc[] = "flag description"; 26 27 template <typename T> 28 static void TestFlag(T start_value, const char *env, T final_value) { 29 T flag = start_value; 30 31 FlagParser parser; 32 RegisterFlag(&parser, kFlagName, kFlagDesc, &flag); 33 34 parser.ParseString(env); 35 36 EXPECT_EQ(final_value, flag); 37 } 38 39 template <> 40 void TestFlag(const char *start_value, const char *env, 41 const char *final_value) { 42 const char *flag = start_value; 43 44 FlagParser parser; 45 RegisterFlag(&parser, kFlagName, kFlagDesc, &flag); 46 47 parser.ParseString(env); 48 49 EXPECT_EQ(0, internal_strcmp(final_value, flag)); 50 51 // Reporting unrecognized flags is needed to reset them. 52 ReportUnrecognizedFlags(); 53 } 54 55 TEST(SanitizerCommon, BooleanFlags) { 56 TestFlag(false, "flag_name=1", true); 57 TestFlag(false, "flag_name=yes", true); 58 TestFlag(false, "flag_name=true", true); 59 TestFlag(true, "flag_name=0", false); 60 TestFlag(true, "flag_name=no", false); 61 TestFlag(true, "flag_name=false", false); 62 } 63 64 TEST(SanitizerCommon, IntFlags) { 65 TestFlag(-11, 0, -11); 66 TestFlag(-11, "flag_name=0", 0); 67 TestFlag(-11, "flag_name=42", 42); 68 TestFlag(-11, "flag_name=-42", -42); 69 70 // Unrecognized flags are ignored. 71 TestFlag(-11, "--flag_name=42", -11); 72 TestFlag(-11, "zzzzzzz=42", -11); 73 74 EXPECT_DEATH(TestFlag(-11, "flag_name", 0), "expected '='"); 75 EXPECT_DEATH(TestFlag(-11, "flag_name=42U", 0), 76 "Invalid value for int option"); 77 } 78 79 TEST(SanitizerCommon, StrFlags) { 80 TestFlag("zzz", 0, "zzz"); 81 TestFlag("zzz", "flag_name=", ""); 82 TestFlag("zzz", "flag_name=abc", "abc"); 83 TestFlag("", "flag_name=abc", "abc"); 84 TestFlag("", "flag_name='abc zxc'", "abc zxc"); 85 // TestStrFlag("", "flag_name=\"abc qwe\" asd", "abc qwe"); 86 } 87 88 static void TestTwoFlags(const char *env, bool expected_flag1, 89 const char *expected_flag2, 90 const char *name1 = "flag1", 91 const char *name2 = "flag2") { 92 bool flag1 = !expected_flag1; 93 const char *flag2 = ""; 94 95 FlagParser parser; 96 RegisterFlag(&parser, name1, kFlagDesc, &flag1); 97 RegisterFlag(&parser, name2, kFlagDesc, &flag2); 98 99 parser.ParseString(env); 100 101 EXPECT_EQ(expected_flag1, flag1); 102 EXPECT_EQ(0, internal_strcmp(flag2, expected_flag2)); 103 104 // Reporting unrecognized flags is needed to reset them. 105 ReportUnrecognizedFlags(); 106 } 107 108 TEST(SanitizerCommon, MultipleFlags) { 109 TestTwoFlags("flag1=1 flag2='zzz'", true, "zzz"); 110 TestTwoFlags("flag2='qxx' flag1=0", false, "qxx"); 111 TestTwoFlags("flag1=false:flag2='zzz'", false, "zzz"); 112 TestTwoFlags("flag2=qxx:flag1=yes", true, "qxx"); 113 TestTwoFlags("flag2=qxx\nflag1=yes", true, "qxx"); 114 TestTwoFlags("flag2=qxx\r\nflag1=yes", true, "qxx"); 115 TestTwoFlags("flag2=qxx\tflag1=yes", true, "qxx"); 116 } 117 118 TEST(SanitizerCommon, CommonSuffixFlags) { 119 TestTwoFlags("flag=1 other_flag='zzz'", true, "zzz", "flag", "other_flag"); 120 TestTwoFlags("other_flag='zzz' flag=1", true, "zzz", "flag", "other_flag"); 121 TestTwoFlags("other_flag=' flag=0 ' flag=1", true, " flag=0 ", "flag", 122 "other_flag"); 123 TestTwoFlags("flag=1 other_flag=' flag=0 '", true, " flag=0 ", "flag", 124 "other_flag"); 125 } 126 127 TEST(SanitizerCommon, CommonFlags) { 128 CommonFlags cf; 129 FlagParser parser; 130 RegisterCommonFlags(&parser, &cf); 131 132 cf.SetDefaults(); 133 EXPECT_TRUE(cf.symbolize); 134 EXPECT_STREQ(".", cf.coverage_dir); 135 136 cf.symbolize = false; 137 cf.coverage = true; 138 cf.coverage_direct = true; 139 cf.log_path = "path/one"; 140 141 parser.ParseString("symbolize=1:coverage_direct=false log_path='path/two'"); 142 EXPECT_TRUE(cf.symbolize); 143 EXPECT_TRUE(cf.coverage); 144 EXPECT_FALSE(cf.coverage_direct); 145 EXPECT_STREQ("path/two", cf.log_path); 146 } 147 148 } // namespace __sanitizer 149