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 static constexpr const char DEFAULT_BACKTRACE_DUMP_PREFIX[] = "/data/local/tmp/backtrace_heap"; 60 61 static constexpr size_t DEFAULT_EXPAND_BYTES = 16; 62 static constexpr size_t MAX_EXPAND_BYTES = 16384; 63 64 static constexpr size_t DEFAULT_FREE_TRACK_ALLOCATIONS = 100; 65 static constexpr size_t MAX_FREE_TRACK_ALLOCATIONS = 16384; 66 67 static constexpr size_t DEFAULT_RECORD_ALLOCS = 8000000; 68 static constexpr size_t MAX_RECORD_ALLOCS = 50000000; 69 static constexpr const char DEFAULT_RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs.txt"; 70 71 const std::unordered_map<std::string, Config::OptionInfo> Config::kOptions = { 72 { 73 "guard", {FRONT_GUARD | REAR_GUARD | TRACK_ALLOCS, &Config::SetGuard}, 74 }, 75 { 76 "front_guard", {FRONT_GUARD | TRACK_ALLOCS, &Config::SetFrontGuard}, 77 }, 78 { 79 "rear_guard", {REAR_GUARD | TRACK_ALLOCS, &Config::SetRearGuard}, 80 }, 81 82 { 83 "backtrace", {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktrace}, 84 }, 85 { 86 "backtrace_enable_on_signal", 87 {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktraceEnableOnSignal}, 88 }, 89 90 { 91 "backtrace_dump_on_exit", {0, &Config::SetBacktraceDumpOnExit}, 92 }, 93 { 94 "backtrace_dump_prefix", {0, &Config::SetBacktraceDumpPrefix}, 95 }, 96 97 { 98 "fill", {FILL_ON_ALLOC | FILL_ON_FREE, &Config::SetFill}, 99 }, 100 { 101 "fill_on_alloc", {FILL_ON_ALLOC, &Config::SetFillOnAlloc}, 102 }, 103 { 104 "fill_on_free", {FILL_ON_FREE, &Config::SetFillOnFree}, 105 }, 106 107 { 108 "expand_alloc", {EXPAND_ALLOC, &Config::SetExpandAlloc}, 109 }, 110 111 { 112 "free_track", {FREE_TRACK | FILL_ON_FREE | TRACK_ALLOCS, &Config::SetFreeTrack}, 113 }, 114 { 115 "free_track_backtrace_num_frames", {0, &Config::SetFreeTrackBacktraceNumFrames}, 116 }, 117 118 { 119 "leak_track", {LEAK_TRACK | TRACK_ALLOCS, &Config::VerifyValueEmpty}, 120 }, 121 122 { 123 "record_allocs", {RECORD_ALLOCS, &Config::SetRecordAllocs}, 124 }, 125 { 126 "record_allocs_file", {0, &Config::SetRecordAllocsFile}, 127 }, 128 129 { 130 "verify_pointers", {TRACK_ALLOCS, &Config::VerifyValueEmpty}, 131 }, 132 }; 133 134 bool Config::ParseValue(const std::string& option, const std::string& value, size_t min_value, 135 size_t max_value, size_t* parsed_value) const { 136 assert(!value.empty()); 137 138 // Parse the value into a size_t value. 139 errno = 0; 140 char* end; 141 long long_value = strtol(value.c_str(), &end, 10); 142 if (errno != 0) { 143 error_log("%s: bad value for option '%s': %s", getprogname(), option.c_str(), strerror(errno)); 144 return false; 145 } 146 if (end == value.c_str()) { 147 error_log("%s: bad value for option '%s'", getprogname(), option.c_str()); 148 return false; 149 } 150 if (static_cast<size_t>(end - value.c_str()) != value.size()) { 151 error_log("%s: bad value for option '%s', non space found after option: %s", getprogname(), 152 option.c_str(), end); 153 return false; 154 } 155 if (long_value < 0) { 156 error_log("%s: bad value for option '%s', value cannot be negative: %ld", getprogname(), 157 option.c_str(), long_value); 158 return false; 159 } 160 161 if (static_cast<size_t>(long_value) < min_value) { 162 error_log("%s: bad value for option '%s', value must be >= %zu: %ld", getprogname(), 163 option.c_str(), min_value, long_value); 164 return false; 165 } 166 if (static_cast<size_t>(long_value) > max_value) { 167 error_log("%s: bad value for option '%s', value must be <= %zu: %ld", getprogname(), 168 option.c_str(), max_value, long_value); 169 return false; 170 } 171 *parsed_value = static_cast<size_t>(long_value); 172 return true; 173 } 174 175 bool Config::ParseValue(const std::string& option, const std::string& value, size_t default_value, 176 size_t min_value, size_t max_value, size_t* new_value) const { 177 if (value.empty()) { 178 *new_value = default_value; 179 return true; 180 } 181 return ParseValue(option, value, min_value, max_value, new_value); 182 } 183 184 bool Config::SetGuard(const std::string& option, const std::string& value) { 185 if (value.empty()) { 186 // Set the defaults. 187 front_guard_bytes_ = DEFAULT_GUARD_BYTES; 188 rear_guard_bytes_ = DEFAULT_GUARD_BYTES; 189 return true; 190 } 191 192 if (!ParseValue(option, value, 1, MAX_GUARD_BYTES, &rear_guard_bytes_)) { 193 return false; 194 } 195 196 // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to 197 // make sure that the header is aligned properly. 198 front_guard_bytes_ = __BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES); 199 return true; 200 } 201 202 bool Config::SetFrontGuard(const std::string& option, const std::string& value) { 203 if (!ParseValue(option, value, DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, &front_guard_bytes_)) { 204 return false; 205 } 206 // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to 207 // make sure that the header is aligned properly. 208 front_guard_bytes_ = __BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES); 209 return true; 210 } 211 212 bool Config::SetRearGuard(const std::string& option, const std::string& value) { 213 return ParseValue(option, value, DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, &rear_guard_bytes_); 214 } 215 216 bool Config::SetFill(const std::string& option, const std::string& value) { 217 if (value.empty()) { 218 // Set the defaults. 219 fill_on_alloc_bytes_ = SIZE_MAX; 220 fill_on_free_bytes_ = SIZE_MAX; 221 return true; 222 } 223 224 if (!ParseValue(option, value, 1, SIZE_MAX, &fill_on_alloc_bytes_)) { 225 return false; 226 } 227 fill_on_free_bytes_ = fill_on_alloc_bytes_; 228 return true; 229 } 230 231 bool Config::SetFillOnAlloc(const std::string& option, const std::string& value) { 232 return ParseValue(option, value, SIZE_MAX, 1, SIZE_MAX, &fill_on_alloc_bytes_); 233 } 234 235 bool Config::SetFillOnFree(const std::string& option, const std::string& value) { 236 return ParseValue(option, value, SIZE_MAX, 1, SIZE_MAX, &fill_on_free_bytes_); 237 } 238 239 bool Config::SetBacktrace(const std::string& option, const std::string& value) { 240 backtrace_enabled_ = true; 241 return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES, 242 &backtrace_frames_); 243 } 244 245 bool Config::SetBacktraceEnableOnSignal(const std::string& option, const std::string& value) { 246 backtrace_enable_on_signal_ = true; 247 return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES, 248 &backtrace_frames_); 249 } 250 251 bool Config::SetBacktraceDumpOnExit(const std::string& option, const std::string& value) { 252 if (Config::VerifyValueEmpty(option, value)) { 253 backtrace_dump_on_exit_ = true; 254 return true; 255 } 256 return false; 257 } 258 259 bool Config::SetBacktraceDumpPrefix(const std::string&, const std::string& value) { 260 if (value.empty()) { 261 backtrace_dump_prefix_ = DEFAULT_BACKTRACE_DUMP_PREFIX; 262 } else { 263 backtrace_dump_prefix_ = value; 264 } 265 return true; 266 } 267 268 bool Config::SetExpandAlloc(const std::string& option, const std::string& value) { 269 return ParseValue(option, value, DEFAULT_EXPAND_BYTES, 1, MAX_EXPAND_BYTES, &expand_alloc_bytes_); 270 } 271 272 bool Config::SetFreeTrack(const std::string& option, const std::string& value) { 273 // This option enables fill on free, so set the bytes to the default value. 274 if (fill_on_free_bytes_ == 0) { 275 fill_on_free_bytes_ = SIZE_MAX; 276 } 277 if (free_track_backtrace_num_frames_ == 0) { 278 free_track_backtrace_num_frames_ = DEFAULT_BACKTRACE_FRAMES; 279 } 280 281 return ParseValue(option, value, DEFAULT_FREE_TRACK_ALLOCATIONS, 1, MAX_FREE_TRACK_ALLOCATIONS, 282 &free_track_allocations_); 283 } 284 285 bool Config::SetFreeTrackBacktraceNumFrames(const std::string& option, const std::string& value) { 286 return ParseValue(option, value, DEFAULT_BACKTRACE_FRAMES, 0, MAX_BACKTRACE_FRAMES, 287 &free_track_backtrace_num_frames_); 288 } 289 290 bool Config::SetRecordAllocs(const std::string& option, const std::string& value) { 291 if (record_allocs_file_.empty()) { 292 record_allocs_file_ = DEFAULT_RECORD_ALLOCS_FILE; 293 } 294 return ParseValue(option, value, DEFAULT_RECORD_ALLOCS, 1, MAX_RECORD_ALLOCS, 295 &record_allocs_num_entries_); 296 } 297 298 bool Config::SetRecordAllocsFile(const std::string&, const std::string& value) { 299 if (value.empty()) { 300 // Set the default. 301 record_allocs_file_ = DEFAULT_RECORD_ALLOCS_FILE; 302 return true; 303 } 304 record_allocs_file_ = value; 305 return true; 306 } 307 308 bool Config::VerifyValueEmpty(const std::string& option, const std::string& value) { 309 if (!value.empty()) { 310 // This is not valid. 311 error_log("%s: value set for option '%s' which does not take a value", getprogname(), 312 option.c_str()); 313 return false; 314 } 315 return true; 316 } 317 318 void Config::LogUsage() const { 319 error_log("malloc debug options usage:"); 320 error_log(""); 321 error_log(" front_guard[=XX]"); 322 error_log(" Enables a front guard on all allocations. If XX is set"); 323 error_log(" it sets the number of bytes in the guard. The default is"); 324 error_log(" %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES); 325 error_log(""); 326 error_log(" rear_guard[=XX]"); 327 error_log(" Enables a rear guard on all allocations. If XX is set"); 328 error_log(" it sets the number of bytes in the guard. The default is"); 329 error_log(" %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES); 330 error_log(""); 331 error_log(" guard[=XX]"); 332 error_log(" Enables both a front guard and a rear guard on all allocations."); 333 error_log(" If XX is set it sets the number of bytes in both guards."); 334 error_log(" The default is %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, 335 MAX_GUARD_BYTES); 336 error_log(""); 337 error_log(" backtrace[=XX]"); 338 error_log(" Enable capturing the backtrace at the point of allocation."); 339 error_log(" If XX is set it sets the number of backtrace frames."); 340 error_log(" This option also enables dumping the backtrace heap data"); 341 error_log(" when a signal is received. The data is dumped to the file"); 342 error_log(" backtrace_dump_prefix.<PID>.txt."); 343 error_log(" The default is %zu frames, the max number of frames is %zu.", 344 DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 345 error_log(""); 346 error_log(" backtrace_enable_on_signal[=XX]"); 347 error_log(" Enable capturing the backtrace at the point of allocation."); 348 error_log(" The backtrace capture is not enabled until the process"); 349 error_log(" receives a signal. If XX is set it sets the number of backtrace"); 350 error_log(" frames. The default is %zu frames, the max number of frames is %zu.", 351 DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 352 error_log(""); 353 error_log(" backtrace_dump_prefix[=FILE]"); 354 error_log(" This option only has meaning if the backtrace option has been specified."); 355 error_log(" This is the prefix of the name of the file to which backtrace heap"); 356 error_log(" data will be dumped. The file will be named backtrace_dump_prefix.<PID>.txt."); 357 error_log(" The default is %s.", DEFAULT_BACKTRACE_DUMP_PREFIX); 358 359 error_log(""); 360 error_log(" backtrace_dump_on_exit"); 361 error_log(" This option only has meaning if the backtrace option has been specified."); 362 error_log(" This will cause all live allocations to be dumped to the file"); 363 error_log(" backtrace_dump_prefix.<PID>.final.txt."); 364 error_log(" The default is false."); 365 error_log(""); 366 error_log(" fill_on_alloc[=XX]"); 367 error_log(" On first allocation, fill with the value 0x%02x.", DEFAULT_FILL_ALLOC_VALUE); 368 error_log(" If XX is set it will only fill up to XX bytes of the"); 369 error_log(" allocation. The default is to fill the entire allocation."); 370 error_log(""); 371 error_log(" fill_on_free[=XX]"); 372 error_log(" On free, fill with the value 0x%02x. If XX is set it will", 373 DEFAULT_FILL_FREE_VALUE); 374 error_log(" only fill up to XX bytes of the allocation. The default is to"); 375 error_log(" fill the entire allocation."); 376 error_log(""); 377 error_log(" fill[=XX]"); 378 error_log(" On both first allocation free, fill with the value 0x%02x on", 379 DEFAULT_FILL_ALLOC_VALUE); 380 error_log(" first allocation and the value 0x%02x. If XX is set, only fill", 381 DEFAULT_FILL_FREE_VALUE); 382 error_log(" up to XX bytes. The default is to fill the entire allocation."); 383 error_log(""); 384 error_log(" expand_alloc[=XX]"); 385 error_log(" Allocate an extra number of bytes for every allocation call."); 386 error_log(" If XX is set, that is the number of bytes to expand the"); 387 error_log(" allocation by. The default is %zu bytes, the max bytes is %zu.", 388 DEFAULT_EXPAND_BYTES, MAX_EXPAND_BYTES); 389 error_log(""); 390 error_log(" free_track[=XX]"); 391 error_log(" When a pointer is freed, do not free the memory right away."); 392 error_log(" Instead, keep XX of these allocations around and then verify"); 393 error_log(" that they have not been modified when the total number of freed"); 394 error_log(" allocations exceeds the XX amount. When the program terminates,"); 395 error_log(" the rest of these allocations are verified. When this option is"); 396 error_log(" enabled, it automatically records the backtrace at the time of the free."); 397 error_log(" The default is to record %zu allocations, the max allocations", 398 DEFAULT_FREE_TRACK_ALLOCATIONS); 399 error_log(" to record is %zu.", MAX_FREE_TRACK_ALLOCATIONS); 400 error_log(""); 401 error_log(" free_track_backtrace_num_frames[=XX]"); 402 error_log(" This option only has meaning if free_track is set. This indicates"); 403 error_log(" how many backtrace frames to capture when an allocation is freed."); 404 error_log(" If XX is set, that is the number of frames to capture. If XX"); 405 error_log(" is set to zero, then no backtrace will be captured."); 406 error_log(" The default is to record %zu frames, the max number of frames is %zu.", 407 DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 408 error_log(""); 409 error_log(" leak_track"); 410 error_log(" Enable the leak tracking of memory allocations."); 411 error_log(""); 412 error_log(" record_allocs[=XX]"); 413 error_log(" Record every single allocation/free call. When a specific signal"); 414 error_log(" is sent to the process, the contents of recording are written to"); 415 error_log(" a file (%s) and the recording is cleared.", DEFAULT_RECORD_ALLOCS_FILE); 416 error_log(" If XX is set, that is the total number of allocations/frees that can"); 417 error_log(" recorded. of frames to capture. The default value is %zu.", DEFAULT_RECORD_ALLOCS); 418 error_log(" If the allocation list fills up, all further allocations are not recorded."); 419 error_log(""); 420 error_log(" record_allocs_file[=FILE]"); 421 error_log(" This option only has meaning if the record_allocs options has been specified."); 422 error_log(" This is the name of the file to which recording information will be dumped."); 423 error_log(" The default is %s.", DEFAULT_RECORD_ALLOCS_FILE); 424 error_log(""); 425 error_log(" verify_pointers"); 426 error_log(" A lightweight way to verify that free/malloc_usable_size/realloc"); 427 error_log(" are passed valid pointers."); 428 } 429 430 bool Config::GetOption(const char** options_str, std::string* option, std::string* value) { 431 const char* cur = *options_str; 432 // Process each property name we can find. 433 while (isspace(*cur)) ++cur; 434 435 if (*cur == '\0') { 436 *options_str = cur; 437 return false; 438 } 439 440 const char* start = cur; 441 while (!isspace(*cur) && *cur != '=' && *cur != '\0') ++cur; 442 443 *option = std::string(start, cur - start); 444 445 // Skip any spaces after the name. 446 while (isspace(*cur)) ++cur; 447 448 value->clear(); 449 if (*cur == '=') { 450 ++cur; 451 // Skip the space after the equal. 452 while (isspace(*cur)) ++cur; 453 454 start = cur; 455 while (!isspace(*cur) && *cur != '\0') ++cur; 456 457 if (cur != start) { 458 *value = std::string(start, cur - start); 459 } 460 } 461 *options_str = cur; 462 return true; 463 } 464 465 bool Config::Init(const char* options_str) { 466 // Initialize a few default values. 467 fill_alloc_value_ = DEFAULT_FILL_ALLOC_VALUE; 468 fill_free_value_ = DEFAULT_FILL_FREE_VALUE; 469 front_guard_value_ = DEFAULT_FRONT_GUARD_VALUE; 470 rear_guard_value_ = DEFAULT_REAR_GUARD_VALUE; 471 backtrace_signal_ = SIGRTMAX - 19; 472 backtrace_dump_signal_ = SIGRTMAX - 17; 473 record_allocs_signal_ = SIGRTMAX - 18; 474 free_track_backtrace_num_frames_ = 0; 475 record_allocs_file_.clear(); 476 fill_on_free_bytes_ = 0; 477 backtrace_enable_on_signal_ = false; 478 backtrace_enabled_ = false; 479 backtrace_dump_on_exit_ = false; 480 backtrace_dump_prefix_ = DEFAULT_BACKTRACE_DUMP_PREFIX; 481 482 // Process each option name we can find. 483 std::string option; 484 std::string value; 485 bool valid = true; 486 while (GetOption(&options_str, &option, &value)) { 487 auto entry = kOptions.find(option); 488 if (entry == kOptions.end()) { 489 error_log("%s: unknown option %s", getprogname(), option.c_str()); 490 valid = false; 491 break; 492 } 493 494 const OptionInfo* info = &entry->second; 495 auto process_func = info->process_func; 496 if (process_func != nullptr && !(this->*process_func)(option, value)) { 497 valid = false; 498 break; 499 } 500 options_ |= info->option; 501 } 502 503 if (!valid || *options_str != '\0') { 504 LogUsage(); 505 return false; 506 } 507 508 return true; 509 } 510