1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/common/asan_parameters.h"
16 :
17 : #include <windows.h>
18 :
19 : #include <algorithm>
20 :
21 : #include "base/command_line.h"
22 : #include "base/logging.h"
23 : #include "base/strings/string_number_conversions.h"
24 : #include "base/strings/string_tokenizer.h"
25 : #include "base/strings/string_util.h"
26 : #include "base/strings/stringprintf.h"
27 : #include "base/strings/utf_string_conversions.h"
28 :
29 : namespace common {
30 :
31 : namespace {
32 :
33 : using base::CommandLine;
34 :
35 : // Trinary return values used to indicate if a flag was updated or not.
36 : enum FlagResult {
37 : kFlagNotPresent,
38 : kFlagSet,
39 : kFlagError
40 : };
41 :
42 : // Templated utility class for parsing parameter values from a command-line.
43 : // @tparam Converter Defines the types and parsing.
44 : template<typename Parser>
45 : struct UpdateValueFromCommandLine {
46 : // Try to update the value of a variable from a command-line.
47 : // @param cmd_line The command line who might contain a given parameter.
48 : // @param param_name The parameter that we want to read.
49 : // @param value Will receive the value of the parameter if it's present.
50 : // @returns kFlagNotPresent if the flag was not present and left at its
51 : // default; kFlagSet if the flag was present, valid and modified; or
52 : // kFlagError if the flag was present but invalid. Logs an error on
53 : // failure, and an info message on successful parsing.
54 : static FlagResult Do(const base::CommandLine& cmd_line,
55 : const std::string& param_name,
56 E : typename Parser::ValueType* value) {
57 E : DCHECK_NE(reinterpret_cast<Parser::ValueType*>(NULL), value);
58 :
59 E : if (!cmd_line.HasSwitch(param_name))
60 E : return kFlagNotPresent;
61 :
62 E : std::string value_str = cmd_line.GetSwitchValueASCII(param_name);
63 E : Parser::IntermediateType new_value = 0;
64 E : if (!Parser::Convert(value_str, &new_value)) {
65 E : LOG(ERROR) << "Failed to parse \"" << param_name << "\" value of \""
66 : << value_str << "\".";
67 E : return kFlagError;
68 : }
69 :
70 E : *value = new_value;
71 E : VLOG(1) << "Set \"" << param_name << "\" to " << *value << ".";
72 E : return kFlagSet;
73 E : }
74 : };
75 :
76 : // Parses a uint32_t value from a string provided on the command-line.
77 : struct Uint32Parser {
78 : typedef size_t IntermediateType;
79 : typedef uint32_t ValueType;
80 E : static bool Convert(const std::string& value_str, IntermediateType* value) {
81 E : return base::StringToSizeT(value_str, value);
82 E : }
83 : };
84 : typedef UpdateValueFromCommandLine<Uint32Parser> UpdateUint32FromCommandLine;
85 :
86 : // Parses a float value from a string provided on the command-line.
87 : struct FloatParser {
88 : typedef double IntermediateType;
89 : typedef float ValueType;
90 E : static bool Convert(const std::string& value_str, IntermediateType* value) {
91 E : return base::StringToDouble(value_str, value);
92 E : }
93 : };
94 : typedef UpdateValueFromCommandLine<FloatParser> UpdateFloatFromCommandLine;
95 :
96 : // Try to update the value of an array of ignored stack ids from a command-line.
97 : // We expect the values to be in hexadecimal format and separated by a
98 : // semi-colon.
99 : // @param cmd_line The command line to parse.
100 : // @param param_name The parameter that we want to read.
101 : // @param values Will receive the set of parsed values.
102 : // @returns true on success, false otherwise.
103 : bool ReadIgnoredStackIdsFromCommandLine(const base::CommandLine& cmd_line,
104 : const std::string& param_name,
105 E : std::set<AsanStackId>* values) {
106 E : DCHECK(values != NULL);
107 E : if (!cmd_line.HasSwitch(param_name))
108 E : return true;
109 :
110 E : std::string value_str = cmd_line.GetSwitchValueASCII(param_name);
111 E : base::StringTokenizer string_tokenizer(value_str, ";");
112 E : while (string_tokenizer.GetNext()) {
113 E : int64_t new_value = 0;
114 E : if (!base::HexStringToInt64(string_tokenizer.token(), &new_value)) {
115 E : LOG(ERROR) << "Failed to parse \"" << param_name << "\" value of \""
116 : << string_tokenizer.token() << "\".";
117 E : return false;
118 : }
119 :
120 E : VLOG(1) << "Parsed \"" << param_name << "\" value of "
121 : << base::StringPrintf("0x%016llX", new_value) << ".";
122 E : values->insert(static_cast<AsanStackId>(new_value));
123 E : }
124 :
125 E : return true;
126 E : }
127 :
128 : } // namespace
129 :
130 : // SYZYgy Asan Runtime Options.
131 : const char kAsanParametersSectionName[] = ".syzyaro";
132 : const uint32_t kAsanParametersSectionCharacteristics =
133 : IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
134 :
135 : // Default values of HeapProxy parameters
136 : const uint32_t kDefaultQuarantineSize = 16 * 1024 * 1024;
137 : const uint32_t kDefaultQuarantineBlockSize = 4 * 1024 * 1024;
138 : const uint32_t kDefaultTrailerPaddingSize = 0;
139 : const float kDefaultAllocationGuardRate = 1.0;
140 :
141 : // Default values of StackCaptureCache parameters.
142 : const uint32_t kDefaultReportingPeriod = 0;
143 : const uint32_t kDefaultBottomFramesToSkip = 0;
144 :
145 : // Default values of StackCapture parameters.
146 : // From http://msdn.microsoft.com/en-us/library/bb204633.aspx,
147 : // The maximum number of frames which CaptureStackBackTrace can be asked
148 : // to traverse must be less than 63, so this can't be any larger than 62.
149 : const uint32_t kDefaultMaxNumFrames = 62;
150 :
151 : // Default values of AsanRuntime parameters.
152 : const bool kDefaultExitOnFailure = false;
153 : const bool kDefaultCheckHeapOnFailure = true;
154 : const bool kDefaultDisableBreakpadReporting = false;
155 : const bool kDefaultFeatureRandomization = false;
156 : const bool kDefaultReportInvalidAccesses = false;
157 :
158 : // Default values of AsanLogger parameters.
159 : const bool kDefaultMiniDumpOnFailure = false;
160 : const bool kDefaultLogAsText = true;
161 :
162 : // Default values of ZebraBlockHeap parameters.
163 : const uint32_t kDefaultZebraBlockHeapSize = 16 * 1024 * 1024;
164 : const float kDefaultZebraBlockHeapQuarantineRatio = 0.25f;
165 :
166 : // Default values of the BlockHeapManager parameters.
167 : const bool kDefaultEnableRateTargetedHeaps = true;
168 : const bool kDefaultEnableZebraBlockHeap = false;
169 : const bool kDefaultEnableAllocationFilter = false;
170 : const float kDefaultQuarantineFloodFillRate = 0.5f;
171 : const bool kDefaultPreventDuplicateCorruptionCrashes = false;
172 :
173 : // Default values of LargeBlockHeap parameters.
174 : extern const bool kDefaultEnableLargeBlockHeap = true;
175 : // We want to maintain an allocation overhead of around 45%, which has been
176 : // our historic average for Chrome. Overhead in this heap is 2 pages, so want
177 : // 2 / 0.45 = 4.44 < 5 page minimum.
178 : extern const size_t kDefaultLargeAllocationThreshold = 5 * 4096;
179 :
180 : const char kSyzyAsanOptionsEnvVar[] = "SYZYGY_ASAN_OPTIONS";
181 :
182 : // String names of HeapProxy parameters.
183 : const char kParamQuarantineSize[] = "quarantine_size";
184 : const char kParamQuarantineBlockSize[] = "quarantine_block_size";
185 : const char kParamTrailerPaddingSize[] = "trailer_padding_size";
186 : extern const char kParamAllocationGuardRate[] = "allocation_guard_rate";
187 :
188 : // String names of StackCaptureCache parameters.
189 : const char kParamReportingPeriod[] = "compression_reporting_period";
190 : const char kParamBottomFramesToSkip[] = "bottom_frames_to_skip";
191 :
192 : // String names of StackCapture parameters.
193 : const char kParamMaxNumFrames[] = "max_num_frames";
194 :
195 : // String names of AsanRuntime parameters.
196 : const char kParamIgnoredStackIds[] = "ignored_stack_ids";
197 : const char kParamExitOnFailure[] = "exit_on_failure";
198 : const char kParamNoCheckHeapOnFailure[] = "no_check_heap_on_failure";
199 : const char kParamDisableBreakpadReporting[] = "disable_breakpad";
200 : const char kParamFeatureRandomization[] = "feature_randomization";
201 : const char kParamReportInvalidAccesses[] = "report_invalid_accesses";
202 :
203 : // String names of AsanLogger parameters.
204 : const char kParamMiniDumpOnFailure[] = "minidump_on_failure";
205 : const char kParamNoLogAsText[] = "no_log_as_text";
206 :
207 : // String names of ZebraBlockHeap parameters.
208 : const char kParamZebraBlockHeapSize[] = "zebra_block_heap_size";
209 : const char kParamZebraBlockHeapQuarantineRatio[] =
210 : "zebra_block_heap_quarantine_ratio";
211 :
212 : // String names of BlockHeapManager parameters.
213 : const char kParamDisableCtMalloc[] = "disable_ctmalloc";
214 : const char kParamEnableZebraBlockHeap[] = "enable_zebra_block_heap";
215 : const char kParamEnableAllocationFilter[] = "enable_allocation_filter";
216 : const char kParamQuarantineFloodFillRate[] = "quarantine_flood_fill_rate";
217 : const char kParamPreventDuplicateCorruptionCrashes[] =
218 : "prevent_duplicate_corruption_crashes";
219 :
220 : // String names of LargeBlockHeap parameters.
221 : const char kParamDisableLargeBlockHeap[] = "disable_large_block_heap";
222 : const char kParamLargeAllocationThreshold[] = "large_allocation_threshold";
223 :
224 E : InflatedAsanParameters::InflatedAsanParameters() {
225 : // Clear the AsanParameters portion of ourselves.
226 E : ::memset(this, 0, sizeof(AsanParameters));
227 E : }
228 :
229 : FlatAsanParameters::FlatAsanParameters(
230 E : const InflatedAsanParameters& asan_parameters) {
231 E : bool have_ignored_stack_ids = !asan_parameters.ignored_stack_ids_set.empty();
232 :
233 E : size_t struct_size = sizeof(AsanParameters);
234 E : size_t ignored_stack_ids_size = 0;
235 E : if (have_ignored_stack_ids) {
236 E : ignored_stack_ids_size = sizeof(AsanStackId) *
237 : (asan_parameters.ignored_stack_ids_set.size() + 1);
238 : }
239 E : size_t data_size = struct_size + ignored_stack_ids_size;
240 :
241 E : data_.resize(data_size, 0);
242 E : ::memcpy(data_.data(), &asan_parameters, struct_size);
243 :
244 : // Get typed pointers to the underlying data.
245 E : AsanParameters* params = reinterpret_cast<AsanParameters*>(data_.data());
246 E : AsanStackId* ignored_stack_ids = NULL;
247 E : if (have_ignored_stack_ids) {
248 E : ignored_stack_ids = reinterpret_cast<AsanStackId*>(
249 : data_.data() + struct_size);
250 : }
251 :
252 : // Patch things up.
253 : // The structure size is not supposed to be too large to fit into uint32_t.
254 E : params->size = static_cast<uint32_t>(data_size);
255 E : params->ignored_stack_ids = ignored_stack_ids;
256 :
257 E : if (have_ignored_stack_ids) {
258 : // Fill in the ignored stack IDs.
259 : std::set<AsanStackId>::const_iterator id_it =
260 E : asan_parameters.ignored_stack_ids_set.begin();
261 E : for (; id_it != asan_parameters.ignored_stack_ids_set.end(); ++id_it)
262 E : *(ignored_stack_ids++) = *id_it;
263 E : *(ignored_stack_ids++) = 0; // Terminating NULL.
264 E : DCHECK_EQ(data_.data() + data_size,
265 E : reinterpret_cast<uint8_t*>(ignored_stack_ids));
266 : }
267 E : }
268 :
269 E : void SetDefaultAsanParameters(AsanParameters* asan_parameters) {
270 E : DCHECK_NE(reinterpret_cast<AsanParameters*>(NULL), asan_parameters);
271 :
272 E : ::memset(asan_parameters, 0, sizeof(AsanParameters));
273 :
274 E : asan_parameters->size = sizeof(AsanParameters);
275 E : asan_parameters->version = kAsanParametersVersion;
276 E : asan_parameters->quarantine_size = kDefaultQuarantineSize;
277 E : asan_parameters->reporting_period = kDefaultReportingPeriod;
278 E : asan_parameters->bottom_frames_to_skip = kDefaultBottomFramesToSkip;
279 E : asan_parameters->max_num_frames = kDefaultMaxNumFrames;
280 E : asan_parameters->trailer_padding_size = kDefaultTrailerPaddingSize;
281 E : asan_parameters->ignored_stack_ids = NULL;
282 E : asan_parameters->quarantine_block_size = kDefaultQuarantineBlockSize;
283 E : asan_parameters->minidump_on_failure = kDefaultMiniDumpOnFailure;
284 E : asan_parameters->exit_on_failure = kDefaultExitOnFailure;
285 E : asan_parameters->check_heap_on_failure = kDefaultCheckHeapOnFailure;
286 E : asan_parameters->log_as_text = kDefaultLogAsText;
287 E : asan_parameters->disable_breakpad_reporting =
288 : kDefaultDisableBreakpadReporting;
289 E : asan_parameters->allocation_guard_rate = kDefaultAllocationGuardRate;
290 E : asan_parameters->zebra_block_heap_size = kDefaultZebraBlockHeapSize;
291 E : asan_parameters->zebra_block_heap_quarantine_ratio =
292 : kDefaultZebraBlockHeapQuarantineRatio;
293 : // CtMalloc has been deprecated.
294 E : asan_parameters->deprecated_enable_ctmalloc = false;
295 E : asan_parameters->enable_zebra_block_heap = kDefaultEnableZebraBlockHeap;
296 E : asan_parameters->enable_large_block_heap = kDefaultEnableLargeBlockHeap;
297 E : asan_parameters->enable_allocation_filter = kDefaultEnableAllocationFilter;
298 E : asan_parameters->large_allocation_threshold =
299 : kDefaultLargeAllocationThreshold;
300 E : asan_parameters->feature_randomization = kDefaultFeatureRandomization;
301 E : asan_parameters->quarantine_flood_fill_rate =
302 : kDefaultQuarantineFloodFillRate;
303 E : asan_parameters->prevent_duplicate_corruption_crashes =
304 : kDefaultPreventDuplicateCorruptionCrashes;
305 E : asan_parameters->report_invalid_accesses = kDefaultReportInvalidAccesses;
306 E : }
307 :
308 : bool InflateAsanParameters(const AsanParameters* pod_params,
309 E : InflatedAsanParameters* inflated_params) {
310 : // This must be kept up to date with AsanParameters as it evolves.
311 : static const size_t kSizeOfAsanParametersByVersion[] = {
312 : 40, 44, 48, 52, 52, 52, 56, 56, 56, 56, 60, 60, 60, 60, 60};
313 : static_assert(
314 : arraysize(kSizeOfAsanParametersByVersion) == kAsanParametersVersion + 1,
315 : "Size of parameters version out of date.");
316 :
317 E : SetDefaultAsanParameters(inflated_params);
318 :
319 E : const uint8_t* data = reinterpret_cast<const uint8_t*>(pod_params);
320 E : const uint8_t* data_end = data + pod_params->size;
321 :
322 : // This is the size of known POD data in the version of the structure
323 : // being inflated.
324 : size_t min_pod_size = kSizeOfAsanParametersByVersion[
325 E : std::min(kAsanParametersVersion, pod_params->version)];
326 E : const uint8_t* min_pod_end = data + min_pod_size;
327 :
328 : // If we have stack IDs, ensure the pointer is to a valid location.
329 E : if (pod_params->ignored_stack_ids != NULL) {
330 : const uint8_t* ignored_stack_ids =
331 E : reinterpret_cast<const uint8_t*>(pod_params->ignored_stack_ids);
332 E : if (ignored_stack_ids < min_pod_end || ignored_stack_ids >= data_end) {
333 E : LOG(ERROR) << "Invalid ignored_stack_ids pointer.";
334 E : return false;
335 : }
336 : }
337 :
338 : // Only copy as many parameters as the structure contains, or that our version
339 : // of the runtime understands.
340 E : DCHECK_LE(min_pod_size, sizeof(AsanParameters));
341 E : ::memcpy(inflated_params, pod_params, min_pod_size);
342 :
343 : // Patch up the params to reflect our runtime version.
344 E : inflated_params->size = sizeof(AsanParameters);
345 E : inflated_params->version = kAsanParametersVersion;
346 E : (static_cast<AsanParameters*>(inflated_params))->ignored_stack_ids = NULL;
347 :
348 : // Populate the ignored stack ids.
349 E : const AsanStackId* stack_id = pod_params->ignored_stack_ids;
350 E : if (stack_id == NULL)
351 E : return true;
352 E : while (*stack_id != NULL) {
353 E : if (reinterpret_cast<const uint8_t*>(stack_id) > data_end) {
354 E : LOG(ERROR) << "AsanParameters::ignored_stack_ids list is not NULL "
355 : << "terminated.";
356 E : return false;
357 : }
358 E : inflated_params->ignored_stack_ids_set.insert(*stack_id);
359 E : ++stack_id;
360 E : }
361 :
362 E : return true;
363 E : }
364 :
365 : namespace {
366 :
367 : // Parses a boolean flag. Returns true if the flag was present in the given
368 : // command line, and sets the parsed value in |value|. If |name| is "foo" then
369 : // the switches "--foo" and "--enable_foo" will result in |value| being set to
370 : // true. A switch of "--disable_foo" will result in |value| being set to false.
371 : // The presence of none of these switches will result in the function returning
372 : // false, and |value| being left as is.
373 : bool ParseBooleanFlag(const char* name, const base::CommandLine& cmd_line,
374 E : bool* value) {
375 E : DCHECK_NE(static_cast<const char*>(nullptr), name);
376 E : DCHECK_NE(static_cast<bool*>(nullptr), value);
377 :
378 E : std::string raw = std::string("--") + std::string(name);
379 E : std::string enable = std::string("--enable_") + std::string(name);
380 E : std::string disable = std::string("--enable_") + std::string(name);
381 :
382 : // Parse the command-line from left to right so that position matters. This
383 : // allows the same flag to be toggled back and forth on a single command
384 : // line.
385 E : bool ret = false;
386 E : for (const auto& s16 : cmd_line.argv()) {
387 E : std::string s = base::WideToUTF8(s16);
388 E : if (s == raw || s == enable) {
389 E : *value = true;
390 E : ret = true;
391 E : continue;
392 : }
393 :
394 E : if (s == disable) {
395 i : *value = false;
396 i : ret = true;
397 i : continue;
398 : }
399 E : }
400 :
401 E : return ret;
402 E : }
403 :
404 : } // namespace
405 :
406 : bool ParseAsanParameters(const base::StringPiece16& param_string,
407 E : InflatedAsanParameters* asan_parameters) {
408 E : DCHECK_NE(reinterpret_cast<InflatedAsanParameters*>(NULL), asan_parameters);
409 :
410 : // Prepends the flags with a dummy executable name to keep the
411 : // base::CommandLine parser happy.
412 E : std::wstring str(param_string.as_string());
413 E : str.insert(0, L" ");
414 E : str.insert(0, L"dummy.exe");
415 E : base::CommandLine cmd_line = base::CommandLine::FromString(str);
416 :
417 : // Parse the quarantine size flag.
418 : if (UpdateUint32FromCommandLine::Do(cmd_line, kParamQuarantineSize,
419 E : &asan_parameters->quarantine_size) == kFlagError) {
420 E : return false;
421 : }
422 :
423 : // Parse the quarantine block size.
424 : if (UpdateUint32FromCommandLine::Do(cmd_line, kParamQuarantineBlockSize,
425 E : &asan_parameters->quarantine_block_size) == kFlagError) {
426 i : return false;
427 : }
428 :
429 : // Parse the trailer padding size flag.
430 : if (UpdateUint32FromCommandLine::Do(cmd_line, kParamTrailerPaddingSize,
431 E : &asan_parameters->trailer_padding_size) == kFlagError) {
432 i : return false;
433 : }
434 :
435 : // Parse the allocation guard rate.
436 : if (UpdateFloatFromCommandLine::Do(cmd_line, kParamAllocationGuardRate,
437 E : &asan_parameters->allocation_guard_rate) == kFlagError) {
438 i : return false;
439 : }
440 :
441 : // Parse the reporting period flag.
442 : if (UpdateUint32FromCommandLine::Do(cmd_line, kParamReportingPeriod,
443 E : &asan_parameters->reporting_period) == kFlagError) {
444 i : return false;
445 : }
446 :
447 : // Parse the bottom frames to skip flag.
448 : if (UpdateUint32FromCommandLine::Do(cmd_line, kParamBottomFramesToSkip,
449 E : &asan_parameters->bottom_frames_to_skip) == kFlagError) {
450 i : return false;
451 : }
452 :
453 : // Parse the max number of frames flag.
454 : if (UpdateUint32FromCommandLine::Do(cmd_line, kParamMaxNumFrames,
455 E : &asan_parameters->max_num_frames) == kFlagError) {
456 i : return false;
457 : }
458 :
459 : // Parse the ignored stack ids.
460 E : if (!ReadIgnoredStackIdsFromCommandLine(cmd_line, kParamIgnoredStackIds,
461 : &asan_parameters->ignored_stack_ids_set)) {
462 E : return false;
463 : }
464 :
465 : // Parse the zebra block heap size flag.
466 : if (UpdateUint32FromCommandLine::Do(cmd_line, kParamZebraBlockHeapSize,
467 E : &asan_parameters->zebra_block_heap_size) == kFlagError) {
468 i : return false;
469 : }
470 :
471 : // Parse the zebra block heap quarantine ratio flag.
472 : if (UpdateFloatFromCommandLine::Do(cmd_line,
473 : kParamZebraBlockHeapQuarantineRatio,
474 E : &asan_parameters->zebra_block_heap_quarantine_ratio) == kFlagError) {
475 i : return false;
476 : }
477 :
478 : // Parse the large block heap allocation threshold.
479 : if (UpdateUint32FromCommandLine::Do(cmd_line,
480 : kParamLargeAllocationThreshold,
481 E : &asan_parameters->large_allocation_threshold) == kFlagError) {
482 i : return false;
483 : }
484 :
485 : // Parse the quarantine flood-fill rate.
486 : if (UpdateFloatFromCommandLine::Do(cmd_line,
487 : kParamQuarantineFloodFillRate,
488 E : &asan_parameters->quarantine_flood_fill_rate) == kFlagError) {
489 i : return false;
490 : }
491 :
492 : // Parse the other (boolean) flags.
493 : // TODO(chrisha): Transition these all to new style flags.
494 E : if (cmd_line.HasSwitch(kParamMiniDumpOnFailure))
495 E : asan_parameters->minidump_on_failure = true;
496 E : if (cmd_line.HasSwitch(kParamExitOnFailure))
497 E : asan_parameters->exit_on_failure = true;
498 E : if (cmd_line.HasSwitch(kParamNoLogAsText))
499 E : asan_parameters->log_as_text = false;
500 E : if (cmd_line.HasSwitch(kParamNoCheckHeapOnFailure))
501 E : asan_parameters->check_heap_on_failure = false;
502 E : if (cmd_line.HasSwitch(kParamDisableBreakpadReporting))
503 E : asan_parameters->disable_breakpad_reporting = true;
504 E : if (cmd_line.HasSwitch(kParamDisableCtMalloc))
505 i : LOG(WARNING) << "Ignoring deprecated " << kParamDisableCtMalloc << " flag.";
506 E : if (cmd_line.HasSwitch(kParamEnableZebraBlockHeap))
507 E : asan_parameters->enable_zebra_block_heap = true;
508 E : if (cmd_line.HasSwitch(kParamDisableLargeBlockHeap))
509 E : asan_parameters->enable_large_block_heap = false;
510 E : if (cmd_line.HasSwitch(kParamEnableAllocationFilter))
511 E : asan_parameters->enable_allocation_filter = true;
512 E : if (cmd_line.HasSwitch(kParamPreventDuplicateCorruptionCrashes))
513 E : asan_parameters->prevent_duplicate_corruption_crashes = true;
514 E : if (cmd_line.HasSwitch(kParamReportInvalidAccesses))
515 E : asan_parameters->report_invalid_accesses = true;
516 :
517 : // New style boolean flags with both positive and negative setters. This
518 : // allows them to be set one way in the baked in configuration, and set
519 : // another way in the environment specified runtime configuration.
520 E : bool value = false;
521 E : if (ParseBooleanFlag(kParamFeatureRandomization, cmd_line, &value))
522 E : asan_parameters->feature_randomization = value;
523 :
524 E : return true;
525 E : }
526 :
527 : } // namespace common
|