163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris/* 263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * Copyright (C) 2015 The Android Open Source Project 363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * All rights reserved. 463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * 563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * Redistribution and use in source and binary forms, with or without 663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * modification, are permitted provided that the following conditions 763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * are met: 863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * * Redistributions of source code must retain the above copyright 963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * notice, this list of conditions and the following disclaimer. 1063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * * Redistributions in binary form must reproduce the above copyright 1163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * notice, this list of conditions and the following disclaimer in 1263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * the documentation and/or other materials provided with the 1363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * distribution. 1463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * 1563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 2563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris * SUCH DAMAGE. 2763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris */ 2863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 2963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <ctype.h> 3063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <errno.h> 3163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <limits.h> 3263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <signal.h> 3363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <stdlib.h> 3463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <string.h> 3563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <sys/cdefs.h> 3663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 3763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <string> 3863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <vector> 3963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 4063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <sys/system_properties.h> 4163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 4263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include <private/bionic_macros.h> 4363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 4463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include "Config.h" 4563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris#include "debug_log.h" 4663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 47598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris// Config constants 48598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr uint8_t DEFAULT_FILL_ALLOC_VALUE = 0xeb; 49598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr uint8_t DEFAULT_FILL_FREE_VALUE = 0xef; 50598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris 51598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr uint8_t DEFAULT_FRONT_GUARD_VALUE = 0xaa; 52598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr uint8_t DEFAULT_REAR_GUARD_VALUE = 0xbb; 53598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris 54598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris// Used as the default for all guard values. 55598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr size_t DEFAULT_GUARD_BYTES = 32; 56598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr size_t MAX_GUARD_BYTES = 16384; 57598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris 58598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr size_t DEFAULT_BACKTRACE_FRAMES = 16; 59598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr size_t MAX_BACKTRACE_FRAMES = 256; 60598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris 61598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr size_t DEFAULT_EXPAND_BYTES = 16; 62598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr size_t MAX_EXPAND_BYTES = 16384; 63598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris 64598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr size_t DEFAULT_FREE_TRACK_ALLOCATIONS = 100; 65598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferrisstatic constexpr size_t MAX_FREE_TRACK_ALLOCATIONS = 16384; 66598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris 6763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferrisstruct Feature { 68166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris Feature(std::string name, size_t default_value, size_t min_value, size_t max_value, 69166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris uint64_t option, size_t* value, bool* config, bool combo_option) 70166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris : name(name), default_value(default_value), min_value(min_value), max_value(max_value), 71166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris option(option), value(value), config(config), combo_option(combo_option) {} 7263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris std::string name; 7363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris size_t default_value = 0; 74166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris size_t min_value = 0; 75166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris size_t max_value = 0; 7663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 7763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris uint64_t option = 0; 7863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris size_t* value = nullptr; 7963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris bool* config = nullptr; 8063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // If set to true, then all of the options following are set on until 8163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // for which the combo_option value is set. 8263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris bool combo_option = false; 8363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris}; 8463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 8563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferrisclass PropertyParser { 8663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris public: 8763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris PropertyParser(const char* property) : cur_(property) {} 8863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 8963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris bool Get(std::string* property, size_t* value, bool* value_set); 9063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 9163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris bool Done() { return done_; } 9263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 9363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris void LogUsage(); 9463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 9563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris private: 9663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris const char* cur_ = nullptr; 9763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 9863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris bool done_ = false; 9963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 10063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris DISALLOW_COPY_AND_ASSIGN(PropertyParser); 10163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris}; 10263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 10363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferrisbool PropertyParser::Get(std::string* property, size_t* value, bool* value_set) { 10463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Process each property name we can find. 10563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris while (isspace(*cur_)) 10663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris ++cur_; 10763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 10863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (*cur_ == '\0') { 10963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris done_ = true; 11063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return false; 11163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 11263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 11363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris const char* property_start = cur_; 11463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris while (!isspace(*cur_) && *cur_ != '=' && *cur_ != '\0') 11563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris ++cur_; 11663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 11763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris *property = std::string(property_start, cur_ - property_start); 11863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 11963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Skip any spaces after the name. 12063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris while (isspace(*cur_) && *cur_ != '=' && *cur_ != '\0') 12163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris ++cur_; 12263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 12363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (*cur_ == '=') { 12463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris ++cur_; 12563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris errno = 0; 12663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris *value_set = true; 12763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris char* end; 12863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris long read_value = strtol(cur_, const_cast<char**>(&end), 10); 12963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (errno != 0) { 13063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log("%s: bad value for option '%s': %s", getprogname(), property->c_str(), 13163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris strerror(errno)); 13263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return false; 13363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 13463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (cur_ == end || (!isspace(*end) && *end != '\0')) { 13563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (cur_ == end) { 13663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log("%s: bad value for option '%s'", getprogname(), property->c_str()); 13763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } else { 13863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log("%s: bad value for option '%s', non space found after option: %s", 13963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris getprogname(), property->c_str(), end); 14063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 14163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return false; 142166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris } else if (read_value < 0) { 143166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris error_log("%s: bad value for option '%s', value cannot be negative: %ld", 14463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris getprogname(), property->c_str(), read_value); 14563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return false; 14663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 14763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris *value = static_cast<size_t>(read_value); 14863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris cur_ = end; 14963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } else { 15063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris *value_set = false; 15163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 15263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return true; 15363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris} 15463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 15563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferrisvoid PropertyParser::LogUsage() { 15663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log("malloc debug options usage:"); 15763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 15863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" front_guard[=XX]"); 15963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" Enables a front guard on all allocations. If XX is set"); 16063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" it sets the number of bytes in the guard. The default is"); 161598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES); 16263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 16363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" rear_guard[=XX]"); 16463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" Enables a rear guard on all allocations. If XX is set"); 16563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" it sets the number of bytes in the guard. The default is"); 166598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" %zu bytes, the max bytes is %zu.", DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES); 16763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 16863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" guard[=XX]"); 16963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" Enables both a front guard and a rear guard on all allocations."); 17063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" If XX is set it sets the number of bytes in both guards."); 171598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" The default is %zu bytes, the max bytes is %zu.", 172598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris DEFAULT_GUARD_BYTES, MAX_GUARD_BYTES); 17363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 17463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" backtrace[=XX]"); 17563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" Enable capturing the backtrace at the point of allocation."); 17663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" If XX is set it sets the number of backtrace frames."); 177598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" The default is %zu frames, the max number of frames is %zu.", 178598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 17963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 18063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" backtrace_enable_on_signal[=XX]"); 18163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" Enable capturing the backtrace at the point of allocation."); 18263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" The backtrace capture is not enabled until the process"); 18363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" receives a signal. If XX is set it sets the number of backtrace"); 184598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" frames. The default is %zu frames, the max number of frames is %zu.", 185598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 18663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 18763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" fill_on_alloc[=XX]"); 18863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" On first allocation, fill with the value 0x%02x.", DEFAULT_FILL_ALLOC_VALUE); 18963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" If XX is set it will only fill up to XX bytes of the"); 19063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" allocation. The default is to fill the entire allocation."); 19163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 19263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" fill_on_free[=XX]"); 19363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" On free, fill with the value 0x%02x. If XX is set it will", 19463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris DEFAULT_FILL_FREE_VALUE); 19563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" only fill up to XX bytes of the allocation. The default is to"); 19663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" fill the entire allocation."); 19763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 19863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" fill[=XX]"); 19963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" On both first allocation free, fill with the value 0x%02x on", 20063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris DEFAULT_FILL_ALLOC_VALUE); 20163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" first allocation and the value 0x%02x. If XX is set, only fill", 20263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris DEFAULT_FILL_FREE_VALUE); 20363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" up to XX bytes. The default is to fill the entire allocation."); 20463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 20563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" expand_alloc[=XX]"); 20663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" Allocate an extra number of bytes for every allocation call."); 20763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" If XX is set, that is the number of bytes to expand the"); 208598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" allocation by. The default is %zu bytes, the max bytes is %zu.", 209598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris DEFAULT_EXPAND_BYTES, MAX_EXPAND_BYTES); 21063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 21163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" free_track[=XX]"); 21263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" When a pointer is freed, do not free the memory right away."); 21363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" Instead, keep XX of these allocations around and then verify"); 21463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" that they have not been modified when the total number of freed"); 21563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" allocations exceeds the XX amount. When the program terminates,"); 2167993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris error_log(" the rest of these allocations are verified. When this option is"); 2177993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris error_log(" enabled, it automatically records the backtrace at the time of the free."); 218598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" The default is to record %zu allocations, the max allocations", 219598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris DEFAULT_FREE_TRACK_ALLOCATIONS); 220598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" to record is %zu.", MAX_FREE_TRACK_ALLOCATIONS); 22163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(""); 2227993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris error_log(" free_track_backtrace_num_frames[=XX]"); 2237993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris error_log(" This option only has meaning if free_track is set. This indicates"); 2247993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris error_log(" how many backtrace frames to capture when an allocation is freed."); 2257993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris error_log(" If XX is set, that is the number of frames to capture. If XX"); 2267993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris error_log(" is set to zero, then no backtrace will be captured."); 227598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris error_log(" The default is to record %zu frames, the max number of frames is %zu.", 228598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES); 2297993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris error_log(""); 23063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" leak_track"); 23163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log(" Enable the leak tracking of memory allocations."); 23263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris} 23363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 234166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferrisstatic bool SetFeature( 235166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris const std::string name, const Feature& feature, size_t value, bool value_set) { 23663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (feature.config) { 23763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris *feature.config = true; 23863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 23963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (feature.value != nullptr) { 24063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (value_set) { 241166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris if (value < feature.min_value) { 242166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris error_log("%s: bad value for option '%s', value must be >= %zu: %zu", 243166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris getprogname(), name.c_str(), feature.min_value, value); 244166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris return false; 245166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris } else if (value > feature.max_value) { 246166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris error_log("%s: bad value for option '%s', value must be <= %zu: %zu", 247166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris getprogname(), name.c_str(), feature.max_value, value); 248166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris return false; 249166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris } 25063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris *feature.value = value; 25163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } else { 25263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris *feature.value = feature.default_value; 25363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 25463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } else if (value_set) { 25563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log("%s: value set for option '%s' which does not take a value", 256166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris getprogname(), name.c_str()); 25763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return false; 25863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 25963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return true; 26063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris} 26163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 26263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris// This function is designed to be called once. A second call will not 26363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris// reset all variables. 26463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferrisbool Config::SetFromProperties() { 26563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris char property_str[PROP_VALUE_MAX]; 26663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris memset(property_str, 0, sizeof(property_str)); 26763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (!__system_property_get("libc.debug.malloc.options", property_str)) { 26863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return false; 26963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 27063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 27163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Initialize a few default values. 272598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris fill_alloc_value = DEFAULT_FILL_ALLOC_VALUE; 273598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris fill_free_value = DEFAULT_FILL_FREE_VALUE; 274598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris front_guard_value = DEFAULT_FRONT_GUARD_VALUE; 275598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris rear_guard_value = DEFAULT_REAR_GUARD_VALUE; 276258abf70f93ee9231e46111f75cbedbc7cdf4ff9Christopher Ferris backtrace_signal = SIGRTMAX - 19; 2777993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris free_track_backtrace_num_frames = 16; 27863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 27963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Parse the options are of the format: 28063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // option_name or option_name=XX 28163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 28263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Supported features: 28363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris const Feature features[] = { 284598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris Feature("guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, 0, nullptr, nullptr, true), 28563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Enable front guard. Value is the size of the guard. 286598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris Feature("front_guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, FRONT_GUARD, 287598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris &this->front_guard_bytes, nullptr, true), 28863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Enable end guard. Value is the size of the guard. 289598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris Feature("rear_guard", DEFAULT_GUARD_BYTES, 1, MAX_GUARD_BYTES, REAR_GUARD, 290598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris &this->rear_guard_bytes, nullptr, true), 29163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 29263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Enable logging the backtrace on allocation. Value is the total 29363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // number of frames to log. 294598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris Feature("backtrace", DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES, 295598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris BACKTRACE | TRACK_ALLOCS, &this->backtrace_frames, &this->backtrace_enabled, false), 29663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Enable gathering backtrace values on a signal. 297598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris Feature("backtrace_enable_on_signal", DEFAULT_BACKTRACE_FRAMES, 1, MAX_BACKTRACE_FRAMES, 298598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris BACKTRACE | TRACK_ALLOCS, &this->backtrace_frames, &this->backtrace_enable_on_signal, 299598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris false), 30063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 301166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris Feature("fill", SIZE_MAX, 1, SIZE_MAX, 0, nullptr, nullptr, true), 30263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Fill the allocation with an arbitrary pattern on allocation. 30363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Value is the number of bytes of the allocation to fill 30463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // (default entire allocation). 305166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris Feature("fill_on_alloc", SIZE_MAX, 1, SIZE_MAX, FILL_ON_ALLOC, &this->fill_on_alloc_bytes, 306f2b67b85f5e192812212d3176c07e195c0ffa503Christopher Ferris nullptr, true), 30763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Fill the allocation with an arbitrary pattern on free. 30863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Value is the number of bytes of the allocation to fill 30963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // (default entire allocation). 310166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris Feature("fill_on_free", SIZE_MAX, 1, SIZE_MAX, FILL_ON_FREE, &this->fill_on_free_bytes, nullptr, true), 31163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 31263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Expand the size of every alloc by this number bytes. Value is 31363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // the total number of bytes to expand every allocation by. 314598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris Feature ("expand_alloc", DEFAULT_EXPAND_BYTES, 1, MAX_EXPAND_BYTES, EXPAND_ALLOC, 315598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris &this->expand_alloc_bytes, nullptr, false), 31663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 31763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Keep track of the freed allocations and verify at a later date 31863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // that they have not been used. Turning this on, also turns on 31963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // fill on free. 320598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris Feature("free_track", DEFAULT_FREE_TRACK_ALLOCATIONS, 1, MAX_FREE_TRACK_ALLOCATIONS, 321598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris FREE_TRACK | FILL_ON_FREE, &this->free_track_allocations, nullptr, false), 3227993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris // Number of backtrace frames to keep when free_track is enabled. If this 3237993b80f894db20af4d1d154221c42fea6171a3dChristopher Ferris // value is set to zero, no backtrace will be kept. 324598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris Feature("free_track_backtrace_num_frames", DEFAULT_BACKTRACE_FRAMES, 325598e2c0d2ae6b7fbc5eb470e4296c20ed1a011eeChristopher Ferris 0, MAX_BACKTRACE_FRAMES, 0, &this->free_track_backtrace_num_frames, nullptr, false), 32663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 32763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Enable printing leaked allocations. 328166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris Feature("leak_track", 0, 0, 0, LEAK_TRACK | TRACK_ALLOCS, nullptr, nullptr, false), 32963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris }; 33063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 33163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // Process each property name we can find. 33263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris std::string property; 33363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris size_t value; 33463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris bool value_set; 33563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris PropertyParser parser(property_str); 33663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris bool valid = true; 33763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris while (valid && parser.Get(&property, &value, &value_set)) { 3384451b53c3761b46fa33a3e47bfb0c62ca47e5fbbChristopher Ferris bool found = false; 33963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris for (size_t i = 0; i < sizeof(features)/sizeof(Feature); i++) { 34063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (property == features[i].name) { 34163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (features[i].option == 0 && features[i].combo_option) { 34263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris i++; 34363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris for (; i < sizeof(features)/sizeof(Feature) && features[i].combo_option; i++) { 344166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris if (!SetFeature(property, features[i], value, value_set)) { 34563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris valid = false; 34663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris break; 34763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 34863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris options |= features[i].option; 34963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 35063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (!valid) { 35163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris break; 35263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 35363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } else { 354166c8535a5a4253bcb2b04bbd20a2a8c04c44f2cChristopher Ferris if (!SetFeature(property, features[i], value, value_set)) { 35563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris valid = false; 35663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris break; 35763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 35863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris options |= features[i].option; 35963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 36063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris found = true; 36163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris break; 36263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 36363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 36463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (valid && !found) { 36563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris error_log("%s: unknown option %s", getprogname(), property.c_str()); 36663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris valid = false; 36763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris break; 36863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 36963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 37063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 37163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris valid = valid && parser.Done(); 37263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 37363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (valid) { 37439b952cf0a824db1cdc301dd048db0e56d4d5c24Christopher Ferris // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to 37563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // make sure that the header is aligned properly. 37663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if (options & FRONT_GUARD) { 37739b952cf0a824db1cdc301dd048db0e56d4d5c24Christopher Ferris front_guard_bytes = BIONIC_ALIGN(front_guard_bytes, MINIMUM_ALIGNMENT_BYTES); 37863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 37963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 38063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // This situation can occur if the free_track option is specified and 38163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // the fill_on_free option is not. In this case, indicate the whole 38263860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris // allocation should be filled. 38363860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris if ((options & FILL_ON_FREE) && fill_on_free_bytes == 0) { 38463860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris fill_on_free_bytes = SIZE_MAX; 38563860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 38663860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } else { 38763860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris parser.LogUsage(); 38863860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris } 38963860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris 39063860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris return valid; 39163860cb8fd1adf3f679b9b4ad876323a8d65cd9dChristopher Ferris} 392