xref: /llvm-project/compiler-rt/lib/sanitizer_common/tests/sanitizer_flags_test.cpp (revision d6d569fc06361cb2324abf5f36192063ce0b4289)
1*d6d569fcSNico Weber //===-- sanitizer_flags_test.cpp ------------------------------------------===//
2*d6d569fcSNico Weber //
3*d6d569fcSNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*d6d569fcSNico Weber // See https://llvm.org/LICENSE.txt for license information.
5*d6d569fcSNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*d6d569fcSNico Weber //
7*d6d569fcSNico Weber //===----------------------------------------------------------------------===//
8*d6d569fcSNico Weber //
9*d6d569fcSNico Weber // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
10*d6d569fcSNico Weber //
11*d6d569fcSNico Weber //===----------------------------------------------------------------------===//
12*d6d569fcSNico Weber #include "sanitizer_common/sanitizer_common.h"
13*d6d569fcSNico Weber #include "sanitizer_common/sanitizer_flags.h"
14*d6d569fcSNico Weber #include "sanitizer_common/sanitizer_flag_parser.h"
15*d6d569fcSNico Weber #include "sanitizer_common/sanitizer_libc.h"
16*d6d569fcSNico Weber #include "sanitizer_common/sanitizer_allocator_internal.h"
17*d6d569fcSNico Weber #include "gtest/gtest.h"
18*d6d569fcSNico Weber 
19*d6d569fcSNico Weber #include <stdint.h>
20*d6d569fcSNico Weber #include <string.h>
21*d6d569fcSNico Weber 
22*d6d569fcSNico Weber namespace __sanitizer {
23*d6d569fcSNico Weber 
24*d6d569fcSNico Weber static const char kFlagName[] = "flag_name";
25*d6d569fcSNico Weber static const char kFlagDesc[] = "flag description";
26*d6d569fcSNico Weber 
27*d6d569fcSNico Weber template <typename T>
TestFlag(T start_value,const char * env,T final_value)28*d6d569fcSNico Weber static void TestFlag(T start_value, const char *env, T final_value) {
29*d6d569fcSNico Weber   T flag = start_value;
30*d6d569fcSNico Weber 
31*d6d569fcSNico Weber   FlagParser parser;
32*d6d569fcSNico Weber   RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);
33*d6d569fcSNico Weber 
34*d6d569fcSNico Weber   parser.ParseString(env);
35*d6d569fcSNico Weber 
36*d6d569fcSNico Weber   EXPECT_EQ(final_value, flag);
37*d6d569fcSNico Weber 
38*d6d569fcSNico Weber   // Reporting unrecognized flags is needed to reset them.
39*d6d569fcSNico Weber   ReportUnrecognizedFlags();
40*d6d569fcSNico Weber }
41*d6d569fcSNico Weber 
42*d6d569fcSNico Weber template <>
TestFlag(const char * start_value,const char * env,const char * final_value)43*d6d569fcSNico Weber void TestFlag(const char *start_value, const char *env,
44*d6d569fcSNico Weber                      const char *final_value) {
45*d6d569fcSNico Weber   const char *flag = start_value;
46*d6d569fcSNico Weber 
47*d6d569fcSNico Weber   FlagParser parser;
48*d6d569fcSNico Weber   RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);
49*d6d569fcSNico Weber 
50*d6d569fcSNico Weber   parser.ParseString(env);
51*d6d569fcSNico Weber 
52*d6d569fcSNico Weber   EXPECT_EQ(0, internal_strcmp(final_value, flag));
53*d6d569fcSNico Weber 
54*d6d569fcSNico Weber   // Reporting unrecognized flags is needed to reset them.
55*d6d569fcSNico Weber   ReportUnrecognizedFlags();
56*d6d569fcSNico Weber }
57*d6d569fcSNico Weber 
TEST(SanitizerCommon,BooleanFlags)58*d6d569fcSNico Weber TEST(SanitizerCommon, BooleanFlags) {
59*d6d569fcSNico Weber   TestFlag(false, "flag_name=1", true);
60*d6d569fcSNico Weber   TestFlag(false, "flag_name=yes", true);
61*d6d569fcSNico Weber   TestFlag(false, "flag_name=true", true);
62*d6d569fcSNico Weber   TestFlag(true, "flag_name=0", false);
63*d6d569fcSNico Weber   TestFlag(true, "flag_name=no", false);
64*d6d569fcSNico Weber   TestFlag(true, "flag_name=false", false);
65*d6d569fcSNico Weber 
66*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(false, "flag_name", true), "expected '='");
67*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(false, "flag_name=", true),
68*d6d569fcSNico Weber                "Invalid value for bool option: ''");
69*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(false, "flag_name=2", true),
70*d6d569fcSNico Weber                "Invalid value for bool option: '2'");
71*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(false, "flag_name=-1", true),
72*d6d569fcSNico Weber                "Invalid value for bool option: '-1'");
73*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(false, "flag_name=on", true),
74*d6d569fcSNico Weber                "Invalid value for bool option: 'on'");
75*d6d569fcSNico Weber }
76*d6d569fcSNico Weber 
TEST(SanitizerCommon,HandleSignalMode)77*d6d569fcSNico Weber TEST(SanitizerCommon, HandleSignalMode) {
78*d6d569fcSNico Weber   TestFlag(kHandleSignalNo, "flag_name=1", kHandleSignalYes);
79*d6d569fcSNico Weber   TestFlag(kHandleSignalNo, "flag_name=yes", kHandleSignalYes);
80*d6d569fcSNico Weber   TestFlag(kHandleSignalNo, "flag_name=true", kHandleSignalYes);
81*d6d569fcSNico Weber   TestFlag(kHandleSignalYes, "flag_name=0", kHandleSignalNo);
82*d6d569fcSNico Weber   TestFlag(kHandleSignalYes, "flag_name=no", kHandleSignalNo);
83*d6d569fcSNico Weber   TestFlag(kHandleSignalYes, "flag_name=false", kHandleSignalNo);
84*d6d569fcSNico Weber   TestFlag(kHandleSignalNo, "flag_name=2", kHandleSignalExclusive);
85*d6d569fcSNico Weber   TestFlag(kHandleSignalYes, "flag_name=exclusive", kHandleSignalExclusive);
86*d6d569fcSNico Weber 
87*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name", kHandleSignalNo),
88*d6d569fcSNico Weber                "expected '='");
89*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=", kHandleSignalNo),
90*d6d569fcSNico Weber                "Invalid value for signal handler option: ''");
91*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=3", kHandleSignalNo),
92*d6d569fcSNico Weber                "Invalid value for signal handler option: '3'");
93*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=-1", kHandleSignalNo),
94*d6d569fcSNico Weber                "Invalid value for signal handler option: '-1'");
95*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=on", kHandleSignalNo),
96*d6d569fcSNico Weber                "Invalid value for signal handler option: 'on'");
97*d6d569fcSNico Weber }
98*d6d569fcSNico Weber 
TEST(SanitizerCommon,IntFlags)99*d6d569fcSNico Weber TEST(SanitizerCommon, IntFlags) {
100*d6d569fcSNico Weber   TestFlag(-11, 0, -11);
101*d6d569fcSNico Weber   TestFlag(-11, "flag_name=0", 0);
102*d6d569fcSNico Weber   TestFlag(-11, "flag_name=42", 42);
103*d6d569fcSNico Weber   TestFlag(-11, "flag_name=-42", -42);
104*d6d569fcSNico Weber 
105*d6d569fcSNico Weber   // Unrecognized flags are ignored.
106*d6d569fcSNico Weber   TestFlag(-11, "--flag_name=42", -11);
107*d6d569fcSNico Weber   TestFlag(-11, "zzzzzzz=42", -11);
108*d6d569fcSNico Weber 
109*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(-11, "flag_name", 0), "expected '='");
110*d6d569fcSNico Weber   EXPECT_DEATH(TestFlag(-11, "flag_name=42U", 0),
111*d6d569fcSNico Weber                "Invalid value for int option");
112*d6d569fcSNico Weber }
113*d6d569fcSNico Weber 
TEST(SanitizerCommon,LongLongIntFlags)114*d6d569fcSNico Weber TEST(SanitizerCommon, LongLongIntFlags) {
115*d6d569fcSNico Weber   s64 InitValue = -5;
116*d6d569fcSNico Weber   s64 IntMin = INT64_MIN;
117*d6d569fcSNico Weber   s64 IntMax = INT64_MAX;
118*d6d569fcSNico Weber   TestFlag(InitValue, "flag_name=0", 0ll);
119*d6d569fcSNico Weber   TestFlag(InitValue, "flag_name=42", 42ll);
120*d6d569fcSNico Weber   TestFlag(InitValue, "flag_name=-42", -42ll);
121*d6d569fcSNico Weber 
122*d6d569fcSNico Weber   TestFlag(InitValue, "flag_name=-9223372036854775808", IntMin);
123*d6d569fcSNico Weber   TestFlag(InitValue, "flag_name=9223372036854775807", IntMax);
124*d6d569fcSNico Weber 
125*d6d569fcSNico Weber   TestFlag(InitValue, "flag_name=-92233720368547758080000", IntMin);
126*d6d569fcSNico Weber   TestFlag(InitValue, "flag_name=92233720368547758070000", IntMax);
127*d6d569fcSNico Weber }
128*d6d569fcSNico Weber 
TEST(SanitizerCommon,StrFlags)129*d6d569fcSNico Weber TEST(SanitizerCommon, StrFlags) {
130*d6d569fcSNico Weber   TestFlag("zzz", 0, "zzz");
131*d6d569fcSNico Weber   TestFlag("zzz", "flag_name=", "");
132*d6d569fcSNico Weber   TestFlag("zzz", "flag_name=abc", "abc");
133*d6d569fcSNico Weber   TestFlag("", "flag_name=abc", "abc");
134*d6d569fcSNico Weber   TestFlag("", "flag_name='abc zxc'", "abc zxc");
135*d6d569fcSNico Weber   // TestStrFlag("", "flag_name=\"abc qwe\" asd", "abc qwe");
136*d6d569fcSNico Weber }
137*d6d569fcSNico Weber 
TestTwoFlags(const char * env,bool expected_flag1,const char * expected_flag2,const char * name1="flag1",const char * name2="flag2")138*d6d569fcSNico Weber static void TestTwoFlags(const char *env, bool expected_flag1,
139*d6d569fcSNico Weber                          const char *expected_flag2,
140*d6d569fcSNico Weber                          const char *name1 = "flag1",
141*d6d569fcSNico Weber                          const char *name2 = "flag2") {
142*d6d569fcSNico Weber   bool flag1 = !expected_flag1;
143*d6d569fcSNico Weber   const char *flag2 = "";
144*d6d569fcSNico Weber 
145*d6d569fcSNico Weber   FlagParser parser;
146*d6d569fcSNico Weber   RegisterFlag(&parser, name1, kFlagDesc, &flag1);
147*d6d569fcSNico Weber   RegisterFlag(&parser, name2, kFlagDesc, &flag2);
148*d6d569fcSNico Weber 
149*d6d569fcSNico Weber   parser.ParseString(env);
150*d6d569fcSNico Weber 
151*d6d569fcSNico Weber   EXPECT_EQ(expected_flag1, flag1);
152*d6d569fcSNico Weber   EXPECT_EQ(0, internal_strcmp(flag2, expected_flag2));
153*d6d569fcSNico Weber 
154*d6d569fcSNico Weber   // Reporting unrecognized flags is needed to reset them.
155*d6d569fcSNico Weber   ReportUnrecognizedFlags();
156*d6d569fcSNico Weber }
157*d6d569fcSNico Weber 
TEST(SanitizerCommon,MultipleFlags)158*d6d569fcSNico Weber TEST(SanitizerCommon, MultipleFlags) {
159*d6d569fcSNico Weber   TestTwoFlags("flag1=1 flag2='zzz'", true, "zzz");
160*d6d569fcSNico Weber   TestTwoFlags("flag2='qxx' flag1=0", false, "qxx");
161*d6d569fcSNico Weber   TestTwoFlags("flag1=false:flag2='zzz'", false, "zzz");
162*d6d569fcSNico Weber   TestTwoFlags("flag2=qxx:flag1=yes", true, "qxx");
163*d6d569fcSNico Weber   TestTwoFlags("flag2=qxx\nflag1=yes", true, "qxx");
164*d6d569fcSNico Weber   TestTwoFlags("flag2=qxx\r\nflag1=yes", true, "qxx");
165*d6d569fcSNico Weber   TestTwoFlags("flag2=qxx\tflag1=yes", true, "qxx");
166*d6d569fcSNico Weber }
167*d6d569fcSNico Weber 
TEST(SanitizerCommon,CommonSuffixFlags)168*d6d569fcSNico Weber TEST(SanitizerCommon, CommonSuffixFlags) {
169*d6d569fcSNico Weber   TestTwoFlags("flag=1 other_flag='zzz'", true, "zzz", "flag", "other_flag");
170*d6d569fcSNico Weber   TestTwoFlags("other_flag='zzz' flag=1", true, "zzz", "flag", "other_flag");
171*d6d569fcSNico Weber   TestTwoFlags("other_flag=' flag=0 ' flag=1", true, " flag=0 ", "flag",
172*d6d569fcSNico Weber                "other_flag");
173*d6d569fcSNico Weber   TestTwoFlags("flag=1 other_flag=' flag=0 '", true, " flag=0 ", "flag",
174*d6d569fcSNico Weber                "other_flag");
175*d6d569fcSNico Weber }
176*d6d569fcSNico Weber 
TEST(SanitizerCommon,CommonFlags)177*d6d569fcSNico Weber TEST(SanitizerCommon, CommonFlags) {
178*d6d569fcSNico Weber   CommonFlags cf;
179*d6d569fcSNico Weber   FlagParser parser;
180*d6d569fcSNico Weber   RegisterCommonFlags(&parser, &cf);
181*d6d569fcSNico Weber 
182*d6d569fcSNico Weber   cf.SetDefaults();
183*d6d569fcSNico Weber   EXPECT_TRUE(cf.symbolize);
184*d6d569fcSNico Weber   EXPECT_STREQ(".", cf.coverage_dir);
185*d6d569fcSNico Weber 
186*d6d569fcSNico Weber   cf.symbolize = false;
187*d6d569fcSNico Weber   cf.coverage = true;
188*d6d569fcSNico Weber   cf.heap_profile = true;
189*d6d569fcSNico Weber   cf.log_path = "path/one";
190*d6d569fcSNico Weber 
191*d6d569fcSNico Weber   parser.ParseString("symbolize=1:heap_profile=false log_path='path/two'");
192*d6d569fcSNico Weber   EXPECT_TRUE(cf.symbolize);
193*d6d569fcSNico Weber   EXPECT_TRUE(cf.coverage);
194*d6d569fcSNico Weber   EXPECT_FALSE(cf.heap_profile);
195*d6d569fcSNico Weber   EXPECT_STREQ("path/two", cf.log_path);
196*d6d569fcSNico Weber }
197*d6d569fcSNico Weber 
198*d6d569fcSNico Weber }  // namespace __sanitizer
199