15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2005, Google Inc. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// --- 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: Michael Chastain 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a unit test for large allocations in malloc and friends. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "Large" means "so large that they overflow the address space". 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For 32 bits, this means allocations near 2^32 bytes and 2^31 bytes. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For 64 bits, this means allocations near 2^64 bytes and 2^63 bytes. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h> // for size_t, NULL 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> // for malloc, free, realloc 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> // for set, etc 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" // for operator<<, CHECK, etc 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::set; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alloc a size that should always fail. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TryAllocExpectFail(size_t size) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* p1 = malloc(size); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(p1 == NULL); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* p2 = malloc(1); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(p2 != NULL); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* p3 = realloc(p2, size); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(p3 == NULL); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(p2); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alloc a size that might work and might fail. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If it does work, touch some pages. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TryAllocMightFail(size_t size) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* p = static_cast<unsigned char*>(malloc(size)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( p != NULL ) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char volatile* vp = p; // prevent optimizations 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kPoints = 1024; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( size_t i = 0; i < kPoints; ++i ) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vp[i * (size / kPoints)] = static_cast<unsigned char>(i); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( size_t i = 0; i < kPoints; ++i ) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(vp[i * (size / kPoints)] == static_cast<unsigned char>(i)); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vp[size-1] = 'M'; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(vp[size-1] == 'M'); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(p); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main (int argc, char** argv) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate some 0-byte objects. They better be unique. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 0 bytes is not large but it exercises some paths related to 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // large-allocation code. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kZeroTimes = 1024; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Test malloc(0) x %d\n", kZeroTimes); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set<char*> p_set; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( int i = 0; i < kZeroTimes; ++i ) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* p = new char; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(p != NULL); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(p_set.find(p) == p_set.end()); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p_set.insert(p_set.end(), p); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just leak the memory. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Grab some memory so that some later allocations are guaranteed to fail. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Test small malloc\n"); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* p_small = malloc(4*1048576); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(p_small != NULL); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test sizes up near the maximum size_t. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These allocations test the wrap-around code. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Test malloc(0 - N)\n"); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t zero = 0; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kMinusNTimes = 16384; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( size_t i = 1; i < kMinusNTimes; ++i ) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryAllocExpectFail(zero - i); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test sizes a bit smaller. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The small malloc above guarantees that all these return NULL. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Test malloc(0 - 1048576 - N)\n"); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kMinusMBMinusNTimes = 16384; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( size_t i = 0; i < kMinusMBMinusNTimes; ++i) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryAllocExpectFail(zero - 1048576 - i); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test sizes at half of size_t. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These might or might not fail to allocate. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Test malloc(max/2 +- N)\n"); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kHalfPlusMinusTimes = 64; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t half = (zero - 2) / 2 + 1; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( size_t i = 0; i < kHalfPlusMinusTimes; ++i) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryAllocMightFail(half - i); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryAllocMightFail(half + i); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("PASS\n"); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 138