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