sanitizer_flags.cc revision 55c7947a742aa72530eef52d902e60e5571ac3cf
1//===-- sanitizer_flags.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 14#include "sanitizer_flags.h" 15 16#include "sanitizer_common.h" 17#include "sanitizer_libc.h" 18 19namespace __sanitizer { 20 21void SetCommonFlagDefaults() { 22 CommonFlags *f = common_flags(); 23 f->symbolize = true; 24 f->external_symbolizer_path = ""; 25 f->strip_path_prefix = ""; 26 f->fast_unwind_on_fatal = false; 27 f->fast_unwind_on_malloc = true; 28 f->handle_ioctl = false; 29 f->malloc_context_size = 1; 30 f->log_path = "stderr"; 31 f->verbosity = 0; 32 f->detect_leaks = false; 33 f->leak_check_at_exit = true; 34 f->allocator_may_return_null = false; 35} 36 37void ParseCommonFlagsFromString(const char *str) { 38 CommonFlags *f = common_flags(); 39 ParseFlag(str, &f->symbolize, "symbolize"); 40 ParseFlag(str, &f->external_symbolizer_path, "external_symbolizer_path"); 41 ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix"); 42 ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal"); 43 ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc"); 44 ParseFlag(str, &f->handle_ioctl, "handle_ioctl"); 45 ParseFlag(str, &f->malloc_context_size, "malloc_context_size"); 46 ParseFlag(str, &f->log_path, "log_path"); 47 ParseFlag(str, &f->verbosity, "verbosity"); 48 ParseFlag(str, &f->detect_leaks, "detect_leaks"); 49 ParseFlag(str, &f->leak_check_at_exit, "leak_check_at_exit"); 50 ParseFlag(str, &f->allocator_may_return_null, "allocator_may_return_null"); 51 52 // Do a sanity check for certain flags. 53 if (f->malloc_context_size < 1) 54 f->malloc_context_size = 1; 55} 56 57static bool GetFlagValue(const char *env, const char *name, 58 const char **value, int *value_length) { 59 if (env == 0) 60 return false; 61 const char *pos = 0; 62 for (;;) { 63 pos = internal_strstr(env, name); 64 if (pos == 0) 65 return false; 66 if (pos != env && ((pos[-1] >= 'a' && pos[-1] <= 'z') || pos[-1] == '_')) { 67 // Seems to be middle of another flag name or value. 68 env = pos + 1; 69 continue; 70 } 71 break; 72 } 73 pos += internal_strlen(name); 74 const char *end; 75 if (pos[0] != '=') { 76 end = pos; 77 } else { 78 pos += 1; 79 if (pos[0] == '"') { 80 pos += 1; 81 end = internal_strchr(pos, '"'); 82 } else if (pos[0] == '\'') { 83 pos += 1; 84 end = internal_strchr(pos, '\''); 85 } else { 86 // Read until the next space or colon. 87 end = pos + internal_strcspn(pos, " :"); 88 } 89 if (end == 0) 90 end = pos + internal_strlen(pos); 91 } 92 *value = pos; 93 *value_length = end - pos; 94 return true; 95} 96 97static bool StartsWith(const char *flag, int flag_length, const char *value) { 98 if (!flag || !value) 99 return false; 100 int value_length = internal_strlen(value); 101 return (flag_length >= value_length) && 102 (0 == internal_strncmp(flag, value, value_length)); 103} 104 105void ParseFlag(const char *env, bool *flag, const char *name) { 106 const char *value; 107 int value_length; 108 if (!GetFlagValue(env, name, &value, &value_length)) 109 return; 110 if (StartsWith(value, value_length, "0") || 111 StartsWith(value, value_length, "no") || 112 StartsWith(value, value_length, "false")) 113 *flag = false; 114 if (StartsWith(value, value_length, "1") || 115 StartsWith(value, value_length, "yes") || 116 StartsWith(value, value_length, "true")) 117 *flag = true; 118} 119 120void ParseFlag(const char *env, int *flag, const char *name) { 121 const char *value; 122 int value_length; 123 if (!GetFlagValue(env, name, &value, &value_length)) 124 return; 125 *flag = static_cast<int>(internal_atoll(value)); 126} 127 128static LowLevelAllocator allocator_for_flags; 129 130void ParseFlag(const char *env, const char **flag, const char *name) { 131 const char *value; 132 int value_length; 133 if (!GetFlagValue(env, name, &value, &value_length)) 134 return; 135 // Copy the flag value. Don't use locks here, as flags are parsed at 136 // tool startup. 137 char *value_copy = (char*)(allocator_for_flags.Allocate(value_length + 1)); 138 internal_memcpy(value_copy, value, value_length); 139 value_copy[value_length] = '\0'; 140 *flag = value_copy; 141} 142 143} // namespace __sanitizer 144