1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <assert.h> 30 #include <ctype.h> 31 #include <errno.h> 32 #include <limits.h> 33 #include <signal.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <sys/cdefs.h> 37 38 #include <string> 39 #include <vector> 40 41 #include <private/bionic_macros.h> 42 43 #include "Config.h" 44 #include "debug_log.h" 45 46 // Config constants 47 static constexpr uint8_t DEFAULT_FILL_ALLOC_VALUE = 0xeb; 48 static constexpr uint8_t DEFAULT_FILL_FREE_VALUE = 0xef; 49 50 static constexpr uint8_t DEFAULT_FRONT_GUARD_VALUE = 0xaa; 51 static constexpr uint8_t DEFAULT_REAR_GUARD_VALUE = 0xbb; 52 53 // Used as the default for all guard values. 54 static constexpr size_t DEFAULT_GUARD_BYTES = 32; 55 static constexpr size_t MAX_GUARD_BYTES = 16384; 56 57 static constexpr size_t DEFAULT_BACKTRACE_FRAMES = 16; 58 static constexpr size_t MAX_BACKTRACE_FRAMES = 256; 59 60 static constexpr size_t DEFAULT_EXPAND_BYTES = 16; 61 static constexpr size_t MAX_EXPAND_BYTES = 16384; 62 63 static constexpr size_t DEFAULT_FREE_TRACK_ALLOCATIONS = 100; 64 static constexpr size_t MAX_FREE_TRACK_ALLOCATIONS = 16384; 65 66 static constexpr size_t DEFAULT_RECORD_ALLOCS = 8000000; 67 static constexpr size_t MAX_RECORD_ALLOCS = 50000000; 68 static constexpr const char DEFAULT_RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs.txt"; 69 70 const std::unordered_map<std::string, Config::OptionInfo> Config::kOptions = { 71 {"guard", 72 {FRONT_GUARD | REAR_GUARD, &Config::SetGuard}, 73 }, 74 {"front_guard", 75 {FRONT_GUARD, &Config::SetFrontGuard}, 76 }, 77 {"rear_guard", 78 {REAR_GUARD, &Config::SetRearGuard}, 79 }, 80 81 {"backtrace", 82 {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktrace}, 83 }, 84 {"backtrace_enable_on_signal", 85 {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktraceEnableOnSignal}, 86 }, 87 88 {"fill", 89 {FILL_ON_ALLOC | FILL_ON_FREE, &Config::SetFill}, 90 }, 91 {"fill_on_alloc", 92 {FILL_ON_ALLOC, &Config::SetFillOnAlloc}, 93 }, 94 {"fill_on_free", 95 {FILL_ON_FREE, &Config::SetFillOnFree}, 96 }, 97 98 {"expand_alloc", 99 {EXPAND_ALLOC, &Config::SetExpandAlloc}, 100 }, 101 102 {"free_track", 103 {FREE_TRACK | FILL_ON_FREE, &Config::SetFreeTrack}, 104 }, 105 {"free_track_backtrace_num_frames", 106 {0, &Config::SetFreeTrackBacktraceNumFrames}, 107 }, 108 109 {"leak_track", 110 {LEAK_TRACK | TRACK_ALLOCS, &Config::VerifyValueEmpty}, 111 }, 112 113 {"record_allocs", 114 {RECORD_ALLOCS, &Config::SetRecordAllocs}, 115 }, 116 {"record_allocs_file", 117 {0, &Config::SetRecordAllocsFile}, 118 }, 119 }; 120 121 bool Config::ParseValue(const std::string& option, const std::string& value, 122 size_t min_value, size_t max_value, size_t* parsed_value) const { 123 assert(!value.empty()); 124 125 // Parse the value into a size_t value. 126 errno = 0; 127 char* end; 128 long long_value = strtol(value.c_str(), &end, 10); 129 if (errno != 0) { 130 error_log("%s: bad value for option '%s': %s", getprogname(), option.c_str(), 131 strerror(errno)); 132 return false; 133 } 134 if (end == value.c_str()) { 135 error_log("%s: bad value for option '%s'", getprogname(), option.c_str()); 136 return false; 137 } 138 if (static_cast<size_t>(end - value.c_str()) != value.size()) { 139 error_log("%s: bad value for option '%s', non space found after option: %s", 140 getprogname(), option.c_str(), end); 141 return false; 142 } 143 if (long_value < 0) { 144 error_log("%s: bad value for option '%s', value cannot be negative: %ld", 145 getprogname(), option.c_str(), long_value); 146 return false; 147 } 148 149 if (static_cast<size_t>(long_value) < min_value) { 150 error_log("%s: bad value for option '%s', value must be >= %zu: %ld", 151 getprogname(), option.c_str(), min_value, long_value); 152 return false; 153 } 154 if (static_cast<size_t>(long_value) > max_value) { 155 error_log("%s: bad value for option '%s', value must be <= %zu: %ld", 156 getprogname(), option.c_str(), max_value, long_value); 157 return false; 158 } 159 *parsed_value = static_cast<size_t>(long_value); 160 return true; 161 } 162 163 bool Config::ParseValue(const std::string& option, const std::string& value, size_t default_value, 164 size_t min_value, size_t max_value, size_t* new_value) const { 165 if (value.empty()) { 166 *new_value = default_value; 167 return true; 168 } 169 return ParseValue(option, value, min_value, max_value, new_value); 170 } 171 172 bool Config::SetGuard(const std::string& option, const std::string& value) { 173 if (value.empty()) { 174 // Set the defaults. 175 front_guard_bytes_ = DEFAULT_GUARD_BYTES; 176 rear_guard_bytes_ = DEFAULT_GUARD_BYTES; 177 return true; 178 } 179 180 if (!ParseValue(option, value, 1, MAX_GUARD_BYTES, &rear_guard_bytes_)) { 181 return false; 182 } 183 184 // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to 185 // make sure that the header is aligned properly. 186 front_guard_bytes_ = BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES); 187 return true; 188 } 189 190 bool Config::SetFrontGuard(const std::string& option, const std::string& value) { 191 if (!ParseValue(option, value, DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, &front_guard_bytes_)) { 192 return false; 193 } 194 // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to 195 // make sure that the header is aligned properly. 196 front_guard_bytes_ = BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES); 197 return true; 198 } 199 200 bool Config::SetRearGuard(const std::string& option, const std::string& value) { 201 return ParseValue(option, value, DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, &rear_guard_bytes_); 202 } 203 204 bool Config::SetFill(const std::string& option, const std::string& value) { 205 if (value.empty()) { 206 // Set the defaults. 207 fill_on_alloc_bytes_ = SIZE_MAX; 208 fill_on_free_bytes_ = SIZE_MAX; 209 return true; 210 } 211 212 if (!ParseValue(option, value, 1, SIZE_MAX, &fill_on_alloc_bytes_)) { 213 return false; 214 } 215 fill_on_free_bytes_ = fill_on_alloc_bytes_; 216 return true; 217 } 218 219 bool Config::SetFillOnAlloc(const std::string& option, const std::string& value) { 220 return ParseValue(option, value, SIZE_MAX, 1, SIZE_MAX, &fill_on_alloc_bytes_); 221 } 222 223 bool Config::SetFillOnFree(const std::string& option, const std::string& value) { 224 return ParseValue(option, value, SIZE_MAX, 1, SIZE_MAX, &fill_on_free_bytes_); 225 } 226 227 bool Config::SetBacktrace(const std::string& option, const std::string& value) { 228 backtrace_enabled_ = true; 229 return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES, 230 &backtrace_frames_); 231 } 232 233 bool Config::SetBacktraceEnableOnSignal(const std::string& option, const std::string& value) { 234 backtrace_enable_on_signal_ = true; 235 return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES, 236 &backtrace_frames_); 237 } 238 239 bool Config::SetExpandAlloc(const std::string& option, const std::string& value) { 240 return ParseValue(option, value, DEFAULT_EXPAND_BYTES, 1, MAX_EXPAND_BYTES, &expand_alloc_bytes_); 241 } 242 243 bool Config::SetFreeTrack(const std::string& option, const std::string& value) { 244 // This option enables fill on free, so set the bytes to the default value. 245 if (fill_on_free_bytes_ == 0) { 246 fill_on_free_bytes_ = SIZE_MAX; 247 } 248 if (free_track_backtrace_num_frames_ == 0) { 249 free_track_backtrace_num_frames_ = DEFAULT_BACKTRACE_FRAMES; 250 } 251 252 return ParseValue(option, value, DEFAULT_FREE_TRACK_ALLOCATIONS, 1, MAX_FREE_TRACK_ALLOCATIONS, 253 &free_track_allocations_); 254 } 255 256 bool Config::SetFreeTrackBacktraceNumFrames(const std::string& option, const std::string& value) { 257 return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 0, MAX_BACKTRACE_FRAMES, 258 &free_track_backtrace_num_frames_); 259 } 260 261 bool Config::SetRecordAllocs(const std::string& option, const std::string& value) { 262 if (record_allocs_file_.empty()) { 263 record_allocs_file_ = DEFAULT_RECORD_ALLOCS_FILE; 264 } 265 return ParseValue(option, value, DEFAULT_RECORD_ALLOCS, 1, MAX_RECORD_ALLOCS, 266 &record_allocs_num_entries_); 267 } 268 269 bool Config::SetRecordAllocsFile(const std::string&, const std::string& value) { 270 if (value.empty()) { 271 // Set the default. 272 record_allocs_file_ = DEFAULT_RECORD_ALLOCS_FILE; 273 return true; 274 } 275 record_allocs_file_ = value; 276 return true; 277 } 278 279 bool Config::VerifyValueEmpty(const std::string& option, const std::string& value) { 280 if (!value.empty()) { 281 // This is not valid. 282 error_log("%s: value set for option '%s' which does not take a value", 283 getprogname(), option.c_str()); 284 return false; 285 } 286 return true; 287 } 288 289 290 void Config::LogUsage() const { 291 error_log("malloc debug options usage:"); 292 error_log(""); 293 error_log(" front_guard[=XX]"); 294 error_log(" Enables a front guard on all allocations. If XX is set"); 295 error_log(" it sets the number of bytes in the guard. The default is"); 296 error_log(" %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES); 297 error_log(""); 298 error_log(" rear_guard[=XX]"); 299 error_log(" Enables a rear guard on all allocations. If XX is set"); 300 error_log(" it sets the number of bytes in the guard. The default is"); 301 error_log(" %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES); 302 error_log(""); 303 error_log(" guard[=XX]"); 304 error_log(" Enables both a front guard and a rear guard on all allocations."); 305 error_log(" If XX is set it sets the number of bytes in both guards."); 306 error_log(" The default is %zu bytes, the max bytes is %zu.", 307 DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES); 308 error_log(""); 309 error_log(" backtrace[=XX]"); 310 error_log(" Enable capturing the backtrace at the point of allocation."); 311 error_log(" If XX is set it sets the number of backtrace frames."); 312 error_log(" The default is %zu frames, the max number of frames is %zu.", 313 DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 314 error_log(""); 315 error_log(" backtrace_enable_on_signal[=XX]"); 316 error_log(" Enable capturing the backtrace at the point of allocation."); 317 error_log(" The backtrace capture is not enabled until the process"); 318 error_log(" receives a signal. If XX is set it sets the number of backtrace"); 319 error_log(" frames. The default is %zu frames, the max number of frames is %zu.", 320 DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 321 error_log(""); 322 error_log(" fill_on_alloc[=XX]"); 323 error_log(" On first allocation, fill with the value 0x%02x.", DEFAULT_FILL_ALLOC_VALUE); 324 error_log(" If XX is set it will only fill up to XX bytes of the"); 325 error_log(" allocation. The default is to fill the entire allocation."); 326 error_log(""); 327 error_log(" fill_on_free[=XX]"); 328 error_log(" On free, fill with the value 0x%02x. If XX is set it will", 329 DEFAULT_FILL_FREE_VALUE); 330 error_log(" only fill up to XX bytes of the allocation. The default is to"); 331 error_log(" fill the entire allocation."); 332 error_log(""); 333 error_log(" fill[=XX]"); 334 error_log(" On both first allocation free, fill with the value 0x%02x on", 335 DEFAULT_FILL_ALLOC_VALUE); 336 error_log(" first allocation and the value 0x%02x. If XX is set, only fill", 337 DEFAULT_FILL_FREE_VALUE); 338 error_log(" up to XX bytes. The default is to fill the entire allocation."); 339 error_log(""); 340 error_log(" expand_alloc[=XX]"); 341 error_log(" Allocate an extra number of bytes for every allocation call."); 342 error_log(" If XX is set, that is the number of bytes to expand the"); 343 error_log(" allocation by. The default is %zu bytes, the max bytes is %zu.", 344 DEFAULT_EXPAND_BYTES, MAX_EXPAND_BYTES); 345 error_log(""); 346 error_log(" free_track[=XX]"); 347 error_log(" When a pointer is freed, do not free the memory right away."); 348 error_log(" Instead, keep XX of these allocations around and then verify"); 349 error_log(" that they have not been modified when the total number of freed"); 350 error_log(" allocations exceeds the XX amount. When the program terminates,"); 351 error_log(" the rest of these allocations are verified. When this option is"); 352 error_log(" enabled, it automatically records the backtrace at the time of the free."); 353 error_log(" The default is to record %zu allocations, the max allocations", 354 DEFAULT_FREE_TRACK_ALLOCATIONS); 355 error_log(" to record is %zu.", MAX_FREE_TRACK_ALLOCATIONS); 356 error_log(""); 357 error_log(" free_track_backtrace_num_frames[=XX]"); 358 error_log(" This option only has meaning if free_track is set. This indicates"); 359 error_log(" how many backtrace frames to capture when an allocation is freed."); 360 error_log(" If XX is set, that is the number of frames to capture. If XX"); 361 error_log(" is set to zero, then no backtrace will be captured."); 362 error_log(" The default is to record %zu frames, the max number of frames is %zu.", 363 DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 364 error_log(""); 365 error_log(" leak_track"); 366 error_log(" Enable the leak tracking of memory allocations."); 367 error_log(""); 368 error_log(" record_allocs[=XX]"); 369 error_log(" Record every single allocation/free call. When a specific signal"); 370 error_log(" is sent to the process, the contents of recording are written to"); 371 error_log(" a file (%s) and the recording is cleared.", DEFAULT_RECORD_ALLOCS_FILE); 372 error_log(" If XX is set, that is the total number of allocations/frees that can"); 373 error_log(" recorded. of frames to capture. The default value is %zu.", DEFAULT_RECORD_ALLOCS); 374 error_log(" If the allocation list fills up, all further allocations are not recorded."); 375 error_log(""); 376 error_log(" record_allocs_file[=FILE]"); 377 error_log(" This option only has meaning if the record_allocs options has been specified."); 378 error_log(" This is the name of the file to which recording information will be dumped."); 379 error_log(" The default is %s.", DEFAULT_RECORD_ALLOCS_FILE); 380 } 381 382 bool Config::GetOption(const char** options_str, std::string* option, std::string* value) { 383 const char* cur = *options_str; 384 // Process each property name we can find. 385 while (isspace(*cur)) 386 ++cur; 387 388 if (*cur == '\0') { 389 *options_str = cur; 390 return false; 391 } 392 393 const char* start = cur; 394 while (!isspace(*cur) && *cur != '=' && *cur != '\0') 395 ++cur; 396 397 *option = std::string(start, cur - start); 398 399 // Skip any spaces after the name. 400 while (isspace(*cur)) 401 ++cur; 402 403 value->clear(); 404 if (*cur == '=') { 405 ++cur; 406 // Skip the space after the equal. 407 while (isspace(*cur)) 408 ++cur; 409 410 start = cur; 411 while (!isspace(*cur) && *cur != '\0') 412 ++cur; 413 414 if (cur != start) { 415 *value = std::string(start, cur - start); 416 } 417 } 418 *options_str = cur; 419 return true; 420 } 421 422 bool Config::Init(const char* options_str) { 423 // Initialize a few default values. 424 fill_alloc_value_ = DEFAULT_FILL_ALLOC_VALUE; 425 fill_free_value_ = DEFAULT_FILL_FREE_VALUE; 426 front_guard_value_ = DEFAULT_FRONT_GUARD_VALUE; 427 rear_guard_value_ = DEFAULT_REAR_GUARD_VALUE; 428 backtrace_signal_ = SIGRTMAX - 19; 429 record_allocs_signal_ = SIGRTMAX - 18; 430 free_track_backtrace_num_frames_ = 0; 431 record_allocs_file_.clear(); 432 fill_on_free_bytes_ = 0; 433 backtrace_enable_on_signal_ = false; 434 backtrace_enabled_ = false; 435 436 // Process each option name we can find. 437 std::string option; 438 std::string value; 439 bool valid = true; 440 while (GetOption(&options_str, &option, &value)) { 441 auto entry = kOptions.find(option); 442 if (entry == kOptions.end()) { 443 error_log("%s: unknown option %s", getprogname(), option.c_str()); 444 valid = false; 445 break; 446 } 447 448 const OptionInfo* info = &entry->second; 449 auto process_func = info->process_func; 450 if (process_func != nullptr && !(this->*process_func)(option, value)) { 451 valid = false; 452 break; 453 } 454 options_ |= info->option; 455 } 456 457 if (!valid || *options_str != '\0') { 458 LogUsage(); 459 return false; 460 } 461 462 return true; 463 } 464