1// Copyright (c) 2000, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
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
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14//     * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// ---
31// Author: Urs Holzle <opensource@google.com>
32
33#include "config.h"
34#include <errno.h>
35#ifdef HAVE_FCNTL_H
36#include <fcntl.h>
37#endif
38#ifdef HAVE_INTTYPES_H
39#include <inttypes.h>
40#endif
41// We only need malloc.h for struct mallinfo.
42#ifdef HAVE_STRUCT_MALLINFO
43// Malloc can be in several places on older versions of OS X.
44# if defined(HAVE_MALLOC_H)
45# include <malloc.h>
46# elif defined(HAVE_MALLOC_MALLOC_H)
47# include <malloc/malloc.h>
48# elif defined(HAVE_SYS_MALLOC_H)
49# include <sys/malloc.h>
50# endif
51#endif
52#ifdef HAVE_PTHREAD
53#include <pthread.h>
54#endif
55#include <stdarg.h>
56#include <stdio.h>
57#include <string.h>
58#ifdef HAVE_MMAP
59#include <sys/mman.h>
60#endif
61#include <sys/stat.h>
62#include <sys/types.h>
63#ifdef HAVE_UNISTD_H
64#include <unistd.h>
65#endif
66
67#include <gperftools/malloc_extension.h>
68#include <gperftools/malloc_hook.h>
69#include <gperftools/stacktrace.h>
70#include "addressmap-inl.h"
71#include "base/commandlineflags.h"
72#include "base/googleinit.h"
73#include "base/logging.h"
74#include "base/spinlock.h"
75#include "malloc_hook-inl.h"
76#include "symbolize.h"
77
78#define TCMALLOC_USING_DEBUGALLOCATION
79#include "tcmalloc.cc"
80
81// __THROW is defined in glibc systems.  It means, counter-intuitively,
82// "This function will never throw an exception."  It's an optional
83// optimization tool, but we may need to use it to match glibc prototypes.
84#ifndef __THROW    // I guess we're not on a glibc system
85# define __THROW   // __THROW is just an optimization, so ok to make it ""
86#endif
87
88// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
89// form of the name instead.
90#ifndef MAP_ANONYMOUS
91# define MAP_ANONYMOUS MAP_ANON
92#endif
93
94// ========================================================================= //
95
96DEFINE_bool(malloctrace,
97            EnvToBool("TCMALLOC_TRACE", false),
98            "Enables memory (de)allocation tracing to /tmp/google.alloc.");
99#ifdef HAVE_MMAP
100DEFINE_bool(malloc_page_fence,
101            EnvToBool("TCMALLOC_PAGE_FENCE", false),
102            "Enables putting of memory allocations at page boundaries "
103            "with a guard page following the allocation (to catch buffer "
104            "overruns right when they happen).");
105DEFINE_bool(malloc_page_fence_never_reclaim,
106            EnvToBool("TCMALLOC_PAGE_FRANCE_NEVER_RECLAIM", false),
107            "Enables making the virtual address space inaccessible "
108            "upon a deallocation instead of returning it and reusing later.");
109#else
110DEFINE_bool(malloc_page_fence, false, "Not usable (requires mmap)");
111DEFINE_bool(malloc_page_fence_never_reclaim, false, "Not usable (required mmap)");
112#endif
113DEFINE_bool(malloc_reclaim_memory,
114            EnvToBool("TCMALLOC_RECLAIM_MEMORY", true),
115            "If set to false, we never return memory to malloc "
116            "when an object is deallocated. This ensures that all "
117            "heap object addresses are unique.");
118DEFINE_int32(max_free_queue_size,
119             EnvToInt("TCMALLOC_MAX_FREE_QUEUE_SIZE", 10*1024*1024),
120             "If greater than 0, keep freed blocks in a queue instead of "
121             "releasing them to the allocator immediately.  Release them when "
122             "the total size of all blocks in the queue would otherwise exceed "
123             "this limit.");
124
125DEFINE_bool(symbolize_stacktrace,
126            EnvToBool("TCMALLOC_SYMBOLIZE_STACKTRACE", true),
127            "Symbolize the stack trace when provided (on some error exits)");
128
129// If we are LD_PRELOAD-ed against a non-pthreads app, then
130// pthread_once won't be defined.  We declare it here, for that
131// case (with weak linkage) which will cause the non-definition to
132// resolve to NULL.  We can then check for NULL or not in Instance.
133extern "C" int pthread_once(pthread_once_t *, void (*)(void))
134    ATTRIBUTE_WEAK;
135
136// ========================================================================= //
137
138// A safe version of printf() that does not do any allocation and
139// uses very little stack space.
140static void TracePrintf(int fd, const char *fmt, ...)
141  __attribute__ ((__format__ (__printf__, 2, 3)));
142
143// The do_* functions are defined in tcmalloc/tcmalloc.cc,
144// which is included before this file
145// when TCMALLOC_FOR_DEBUGALLOCATION is defined
146// TODO(csilvers): get rid of these now that we are tied to tcmalloc.
147#define BASE_MALLOC_NEW    do_malloc
148#define BASE_MALLOC        do_malloc
149#define BASE_FREE          do_free
150#define BASE_MALLOC_STATS  do_malloc_stats
151#define BASE_MALLOPT       do_mallopt
152#define BASE_MALLINFO      do_mallinfo
153
154// ========================================================================= //
155
156class MallocBlock;
157
158// A circular buffer to hold freed blocks of memory.  MallocBlock::Deallocate
159// (below) pushes blocks into this queue instead of returning them to the
160// underlying allocator immediately.  See MallocBlock::Deallocate for more
161// information.
162//
163// We can't use an STL class for this because we need to be careful not to
164// perform any heap de-allocations in any of the code in this class, since the
165// code in MallocBlock::Deallocate is not re-entrant.
166template <typename QueueEntry>
167class FreeQueue {
168 public:
169  FreeQueue() : q_front_(0), q_back_(0) {}
170
171  bool Full() {
172    return (q_front_ + 1) % kFreeQueueSize == q_back_;
173  }
174
175  void Push(const QueueEntry& block) {
176    q_[q_front_] = block;
177    q_front_ = (q_front_ + 1) % kFreeQueueSize;
178  }
179
180  QueueEntry Pop() {
181    RAW_CHECK(q_back_ != q_front_, "Queue is empty");
182    const QueueEntry& ret = q_[q_back_];
183    q_back_ = (q_back_ + 1) % kFreeQueueSize;
184    return ret;
185  }
186
187  size_t size() const {
188    return (q_front_ - q_back_ + kFreeQueueSize) % kFreeQueueSize;
189  }
190
191 private:
192  // Maximum number of blocks kept in the free queue before being freed.
193  static const int kFreeQueueSize = 1024;
194
195  QueueEntry q_[kFreeQueueSize];
196  int q_front_;
197  int q_back_;
198};
199
200struct MallocBlockQueueEntry {
201  MallocBlockQueueEntry() : block(NULL), size(0),
202                            num_deleter_pcs(0), deleter_threadid(0) {}
203  MallocBlockQueueEntry(MallocBlock* b, size_t s) : block(b), size(s) {
204    if (FLAGS_max_free_queue_size != 0 && b != NULL) {
205      // Adjust the number of frames to skip (4) if you change the
206      // location of this call.
207      num_deleter_pcs =
208          GetStackTrace(deleter_pcs,
209                        sizeof(deleter_pcs) / sizeof(deleter_pcs[0]),
210                        4);
211      deleter_threadid = pthread_self();
212    } else {
213      num_deleter_pcs = 0;
214      // Zero is an illegal pthread id by my reading of the pthread
215      // implementation:
216      deleter_threadid = 0;
217    }
218  }
219
220  MallocBlock* block;
221  size_t size;
222
223  // When deleted and put in the free queue, we (flag-controlled)
224  // record the stack so that if corruption is later found, we can
225  // print the deleter's stack.  (These three vars add 144 bytes of
226  // overhead under the LP64 data model.)
227  void* deleter_pcs[16];
228  int num_deleter_pcs;
229  pthread_t deleter_threadid;
230};
231
232class MallocBlock {
233 public:  // allocation type constants
234
235  // Different allocation types we distinguish.
236  // Note: The lower 4 bits are not random: we index kAllocName array
237  // by these values masked with kAllocTypeMask;
238  // the rest are "random" magic bits to help catch memory corruption.
239  static const int kMallocType = 0xEFCDAB90;
240  static const int kNewType = 0xFEBADC81;
241  static const int kArrayNewType = 0xBCEADF72;
242
243 private:  // constants
244
245  // A mask used on alloc types above to get to 0, 1, 2
246  static const int kAllocTypeMask = 0x3;
247  // An additional bit to set in AllocType constants
248  // to mark now deallocated regions.
249  static const int kDeallocatedTypeBit = 0x4;
250
251  // For better memory debugging, we initialize all storage to known
252  // values, and overwrite the storage when it's deallocated:
253  // Byte that fills uninitialized storage.
254  static const int kMagicUninitializedByte = 0xAB;
255  // Byte that fills deallocated storage.
256  // NOTE: tcmalloc.cc depends on the value of kMagicDeletedByte
257  //       to work around a bug in the pthread library.
258  static const int kMagicDeletedByte = 0xCD;
259  // A size_t (type of alloc_type_ below) in a deallocated storage
260  // filled with kMagicDeletedByte.
261  static const size_t kMagicDeletedSizeT =
262      0xCDCDCDCD | (((size_t)0xCDCDCDCD << 16) << 16);
263    // Initializer works for 32 and 64 bit size_ts;
264    // "<< 16 << 16" is to fool gcc from issuing a warning
265    // when size_ts are 32 bits.
266
267  // NOTE: on Linux, you can enable malloc debugging support in libc by
268  // setting the environment variable MALLOC_CHECK_ to 1 before you
269  // start the program (see man malloc).
270
271  // We use either BASE_MALLOC or mmap to make the actual allocation. In
272  // order to remember which one of the two was used for any block, we store an
273  // appropriate magic word next to the block.
274  static const int kMagicMalloc = 0xDEADBEEF;
275  static const int kMagicMMap = 0xABCDEFAB;
276
277  // This array will be filled with 0xCD, for use with memcmp.
278  static unsigned char kMagicDeletedBuffer[1024];
279  static pthread_once_t deleted_buffer_initialized_;
280  static bool deleted_buffer_initialized_no_pthreads_;
281
282 private:  // data layout
283
284                    // The four fields size1_,offset_,magic1_,alloc_type_
285                    // should together occupy a multiple of 16 bytes. (At the
286                    // moment, sizeof(size_t) == 4 or 8 depending on piii vs
287                    // k8, and 4 of those sum to 16 or 32 bytes).
288                    // This, combined with BASE_MALLOC's alignment guarantees,
289                    // ensures that SSE types can be stored into the returned
290                    // block, at &size2_.
291  size_t size1_;
292  size_t offset_;   // normally 0 unless memaligned memory
293                    // see comments in memalign() and FromRawPointer().
294  size_t magic1_;
295  size_t alloc_type_;
296  // here comes the actual data (variable length)
297  // ...
298  // then come the size2_ and magic2_, or a full page of mprotect-ed memory
299  // if the malloc_page_fence feature is enabled.
300  size_t size2_;
301  int magic2_;
302
303 private:  // static data and helpers
304
305  // Allocation map: stores the allocation type for each allocated object,
306  // or the type or'ed with kDeallocatedTypeBit
307  // for each formerly allocated object.
308  typedef AddressMap<int> AllocMap;
309  static AllocMap* alloc_map_;
310  // This protects alloc_map_ and consistent state of metadata
311  // for each still-allocated object in it.
312  // We use spin locks instead of pthread_mutex_t locks
313  // to prevent crashes via calls to pthread_mutex_(un)lock
314  // for the (de)allocations coming from pthreads initialization itself.
315  static SpinLock alloc_map_lock_;
316
317  // A queue of freed blocks.  Instead of releasing blocks to the allocator
318  // immediately, we put them in a queue, freeing them only when necessary
319  // to keep the total size of all the freed blocks below the limit set by
320  // FLAGS_max_free_queue_size.
321  static FreeQueue<MallocBlockQueueEntry>* free_queue_;
322
323  static size_t free_queue_size_;  // total size of blocks in free_queue_
324  // protects free_queue_ and free_queue_size_
325  static SpinLock free_queue_lock_;
326
327  // Names of allocation types (kMallocType, kNewType, kArrayNewType)
328  static const char* const kAllocName[];
329  // Names of corresponding deallocation types
330  static const char* const kDeallocName[];
331
332  static const char* AllocName(int type) {
333    return kAllocName[type & kAllocTypeMask];
334  }
335
336  static const char* DeallocName(int type) {
337    return kDeallocName[type & kAllocTypeMask];
338  }
339
340 private:  // helper accessors
341
342  bool IsMMapped() const { return kMagicMMap == magic1_; }
343
344  bool IsValidMagicValue(int value) const {
345    return kMagicMMap == value  ||  kMagicMalloc == value;
346  }
347
348  static size_t real_malloced_size(size_t size) {
349    return size + sizeof(MallocBlock);
350  }
351  static size_t real_mmapped_size(size_t size) {
352    return size + MallocBlock::data_offset();
353  }
354
355  size_t real_size() {
356    return IsMMapped() ? real_mmapped_size(size1_) : real_malloced_size(size1_);
357  }
358
359  // NOTE: if the block is mmapped (that is, we're using the
360  // malloc_page_fence option) then there's no size2 or magic2
361  // (instead, the guard page begins where size2 would be).
362
363  size_t* size2_addr() { return (size_t*)((char*)&size2_ + size1_); }
364  const size_t* size2_addr() const {
365    return (const size_t*)((char*)&size2_ + size1_);
366  }
367
368  int* magic2_addr() { return (int*)(size2_addr() + 1); }
369  const int* magic2_addr() const { return (const int*)(size2_addr() + 1); }
370
371 private:  // other helpers
372
373  void Initialize(size_t size, int type) {
374    RAW_CHECK(IsValidMagicValue(magic1_), "");
375    // record us as allocated in the map
376    alloc_map_lock_.Lock();
377    if (!alloc_map_) {
378      void* p = BASE_MALLOC(sizeof(AllocMap));
379      alloc_map_ = new(p) AllocMap(BASE_MALLOC, BASE_FREE);
380    }
381    alloc_map_->Insert(data_addr(), type);
382    // initialize us
383    size1_ = size;
384    offset_ = 0;
385    alloc_type_ = type;
386    if (!IsMMapped()) {
387      *magic2_addr() = magic1_;
388      *size2_addr() = size;
389    }
390    alloc_map_lock_.Unlock();
391    memset(data_addr(), kMagicUninitializedByte, size);
392    if (!IsMMapped()) {
393      RAW_CHECK(size1_ == *size2_addr(), "should hold");
394      RAW_CHECK(magic1_ == *magic2_addr(), "should hold");
395    }
396  }
397
398  size_t CheckAndClear(int type) {
399    alloc_map_lock_.Lock();
400    CheckLocked(type);
401    if (!IsMMapped()) {
402      RAW_CHECK(size1_ == *size2_addr(), "should hold");
403    }
404    // record us as deallocated in the map
405    alloc_map_->Insert(data_addr(), type | kDeallocatedTypeBit);
406    alloc_map_lock_.Unlock();
407    // clear us
408    const size_t size = real_size();
409    memset(this, kMagicDeletedByte, size);
410    return size;
411  }
412
413  void CheckLocked(int type) const {
414    int map_type = 0;
415    const int* found_type =
416      alloc_map_ != NULL ? alloc_map_->Find(data_addr()) : NULL;
417    if (found_type == NULL) {
418      RAW_LOG(FATAL, "memory allocation bug: object at %p "
419                     "has never been allocated", data_addr());
420    } else {
421      map_type = *found_type;
422    }
423    if ((map_type & kDeallocatedTypeBit) != 0) {
424      RAW_LOG(FATAL, "memory allocation bug: object at %p "
425                     "has been already deallocated (it was allocated with %s)",
426                     data_addr(), AllocName(map_type & ~kDeallocatedTypeBit));
427    }
428    if (alloc_type_ == kMagicDeletedSizeT) {
429      RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
430                     "has been corrupted; or else the object has been already "
431                     "deallocated and our memory map has been corrupted",
432                     data_addr());
433    }
434    if (!IsValidMagicValue(magic1_)) {
435      RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
436                     "has been corrupted; "
437                     "or else our memory map has been corrupted and this is a "
438                     "deallocation for not (currently) heap-allocated object",
439                     data_addr());
440    }
441    if (!IsMMapped()) {
442      if (size1_ != *size2_addr()) {
443        RAW_LOG(FATAL, "memory stomping bug: a word after object at %p "
444                       "has been corrupted", data_addr());
445      }
446      if (!IsValidMagicValue(*magic2_addr())) {
447        RAW_LOG(FATAL, "memory stomping bug: a word after object at %p "
448                "has been corrupted", data_addr());
449      }
450    }
451    if (alloc_type_ != type) {
452      if ((alloc_type_ != MallocBlock::kMallocType) &&
453          (alloc_type_ != MallocBlock::kNewType)    &&
454          (alloc_type_ != MallocBlock::kArrayNewType)) {
455        RAW_LOG(FATAL, "memory stomping bug: a word before object at %p "
456                       "has been corrupted", data_addr());
457      }
458      RAW_LOG(FATAL, "memory allocation/deallocation mismatch at %p: "
459                     "allocated with %s being deallocated with %s",
460                     data_addr(), AllocName(alloc_type_), DeallocName(type));
461    }
462    if (alloc_type_ != map_type) {
463      RAW_LOG(FATAL, "memory stomping bug: our memory map has been corrupted : "
464                     "allocation at %p made with %s "
465                     "is recorded in the map to be made with %s",
466                     data_addr(), AllocName(alloc_type_),  AllocName(map_type));
467    }
468  }
469
470 public:  // public accessors
471
472  void* data_addr() { return (void*)&size2_; }
473  const void* data_addr() const { return (const void*)&size2_; }
474
475  static size_t data_offset() { return OFFSETOF_MEMBER(MallocBlock, size2_); }
476
477  size_t data_size() const { return size1_; }
478
479  void set_offset(int offset) { this->offset_ = offset; }
480
481 public:  // our main interface
482
483  static MallocBlock* Allocate(size_t size, int type) {
484    // Prevent an integer overflow / crash with large allocation sizes.
485    // TODO - Note that for a e.g. 64-bit size_t, max_size_t may not actually
486    // be the maximum value, depending on how the compiler treats ~0. The worst
487    // practical effect is that allocations are limited to 4Gb or so, even if
488    // the address space could take more.
489    static size_t max_size_t = ~0;
490    if (size > max_size_t - sizeof(MallocBlock)) {
491      RAW_LOG(ERROR, "Massive size passed to malloc: %"PRIuS"", size);
492      return NULL;
493    }
494    MallocBlock* b = NULL;
495    const bool use_malloc_page_fence = FLAGS_malloc_page_fence;
496#ifdef HAVE_MMAP
497    if (use_malloc_page_fence) {
498      // Put the block towards the end of the page and make the next page
499      // inaccessible. This will catch buffer overrun right when it happens.
500      size_t sz = real_mmapped_size(size);
501      int pagesize = getpagesize();
502      int num_pages = (sz + pagesize - 1) / pagesize + 1;
503      char* p = (char*) mmap(NULL, num_pages * pagesize, PROT_READ|PROT_WRITE,
504                             MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
505      if (p == MAP_FAILED) {
506        // If the allocation fails, abort rather than returning NULL to
507        // malloc. This is because in most cases, the program will run out
508        // of memory in this mode due to tremendous amount of wastage. There
509        // is no point in propagating the error elsewhere.
510        RAW_LOG(FATAL, "Out of memory: possibly due to page fence overhead: %s",
511                strerror(errno));
512      }
513      // Mark the page after the block inaccessible
514      if (mprotect(p + (num_pages - 1) * pagesize, pagesize, PROT_NONE)) {
515        RAW_LOG(FATAL, "Guard page setup failed: %s", strerror(errno));
516      }
517      b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz);
518    } else {
519      b = (MallocBlock*) (type == kMallocType ?
520                          BASE_MALLOC(real_malloced_size(size)) :
521                          BASE_MALLOC_NEW(real_malloced_size(size)));
522    }
523#else
524    b = (MallocBlock*) (type == kMallocType ?
525                        BASE_MALLOC(real_malloced_size(size)) :
526                        BASE_MALLOC_NEW(real_malloced_size(size)));
527#endif
528
529    // It would be nice to output a diagnostic on allocation failure
530    // here, but logging (other than FATAL) requires allocating
531    // memory, which could trigger a nasty recursion. Instead, preserve
532    // malloc semantics and return NULL on failure.
533    if (b != NULL) {
534      b->magic1_ = use_malloc_page_fence ? kMagicMMap : kMagicMalloc;
535      b->Initialize(size, type);
536    }
537    return b;
538  }
539
540  void Deallocate(int type) {
541    if (IsMMapped()) {  // have to do this before CheckAndClear
542#ifdef HAVE_MMAP
543      int size = CheckAndClear(type);
544      int pagesize = getpagesize();
545      int num_pages = (size + pagesize - 1) / pagesize + 1;
546      char* p = (char*) this;
547      if (FLAGS_malloc_page_fence_never_reclaim  ||
548          !FLAGS_malloc_reclaim_memory) {
549        mprotect(p - (num_pages - 1) * pagesize + size,
550                 num_pages * pagesize, PROT_NONE);
551      } else {
552        munmap(p - (num_pages - 1) * pagesize + size, num_pages * pagesize);
553      }
554#endif
555    } else {
556      const size_t size = CheckAndClear(type);
557      if (FLAGS_malloc_reclaim_memory) {
558        // Instead of freeing the block immediately, push it onto a queue of
559        // recently freed blocks.  Free only enough blocks to keep from
560        // exceeding the capacity of the queue or causing the total amount of
561        // un-released memory in the queue from exceeding
562        // FLAGS_max_free_queue_size.
563        ProcessFreeQueue(this, size, FLAGS_max_free_queue_size);
564      }
565    }
566  }
567
568  static size_t FreeQueueSize() {
569    SpinLockHolder l(&free_queue_lock_);
570    return free_queue_size_;
571  }
572
573  static void ProcessFreeQueue(MallocBlock* b, size_t size,
574                               int max_free_queue_size) {
575    // MallocBlockQueueEntry are about 144 in size, so we can only
576    // use a small array of them on the stack.
577    MallocBlockQueueEntry entries[4];
578    int num_entries = 0;
579    MallocBlockQueueEntry new_entry(b, size);
580    free_queue_lock_.Lock();
581    if (free_queue_ == NULL)
582      free_queue_ = new FreeQueue<MallocBlockQueueEntry>;
583    RAW_CHECK(!free_queue_->Full(), "Free queue mustn't be full!");
584
585    if (b != NULL) {
586      free_queue_size_ += size + sizeof(MallocBlockQueueEntry);
587      free_queue_->Push(new_entry);
588    }
589
590    // Free blocks until the total size of unfreed blocks no longer exceeds
591    // max_free_queue_size, and the free queue has at least one free
592    // space in it.
593    while (free_queue_size_ > max_free_queue_size || free_queue_->Full()) {
594      RAW_CHECK(num_entries < arraysize(entries), "entries array overflow");
595      entries[num_entries] = free_queue_->Pop();
596      free_queue_size_ -=
597          entries[num_entries].size + sizeof(MallocBlockQueueEntry);
598      num_entries++;
599      if (num_entries == arraysize(entries)) {
600        // The queue will not be full at this point, so it is ok to
601        // release the lock.  The queue may still contain more than
602        // max_free_queue_size, but this is not a strict invariant.
603        free_queue_lock_.Unlock();
604        for (int i = 0; i < num_entries; i++) {
605          CheckForDanglingWrites(entries[i]);
606          BASE_FREE(entries[i].block);
607        }
608        num_entries = 0;
609        free_queue_lock_.Lock();
610      }
611    }
612    RAW_CHECK(free_queue_size_ >= 0, "Free queue size went negative!");
613    free_queue_lock_.Unlock();
614    for (int i = 0; i < num_entries; i++) {
615      CheckForDanglingWrites(entries[i]);
616      BASE_FREE(entries[i].block);
617    }
618  }
619
620  static void InitDeletedBuffer() {
621    memset(kMagicDeletedBuffer, kMagicDeletedByte, sizeof(kMagicDeletedBuffer));
622    deleted_buffer_initialized_no_pthreads_ = true;
623  }
624
625  static void CheckForDanglingWrites(const MallocBlockQueueEntry& queue_entry) {
626    // Initialize the buffer if necessary.
627    if (pthread_once)
628      pthread_once(&deleted_buffer_initialized_, &InitDeletedBuffer);
629    if (!deleted_buffer_initialized_no_pthreads_) {
630      // This will be the case on systems that don't link in pthreads,
631      // including on FreeBSD where pthread_once has a non-zero address
632      // (but doesn't do anything) even when pthreads isn't linked in.
633      InitDeletedBuffer();
634    }
635
636    const unsigned char* p =
637        reinterpret_cast<unsigned char*>(queue_entry.block);
638
639    static const size_t size_of_buffer = sizeof(kMagicDeletedBuffer);
640    const size_t size = queue_entry.size;
641    const size_t buffers = size / size_of_buffer;
642    const size_t remainder = size % size_of_buffer;
643    size_t buffer_idx;
644    for (buffer_idx = 0; buffer_idx < buffers; ++buffer_idx) {
645      CheckForCorruptedBuffer(queue_entry, buffer_idx, p, size_of_buffer);
646      p += size_of_buffer;
647    }
648    CheckForCorruptedBuffer(queue_entry, buffer_idx, p, remainder);
649  }
650
651  static void CheckForCorruptedBuffer(const MallocBlockQueueEntry& queue_entry,
652                                      size_t buffer_idx,
653                                      const unsigned char* buffer,
654                                      size_t size_of_buffer) {
655    if (memcmp(buffer, kMagicDeletedBuffer, size_of_buffer) == 0) {
656      return;
657    }
658
659    RAW_LOG(ERROR,
660            "Found a corrupted memory buffer in MallocBlock (may be offset "
661            "from user ptr): buffer index: %zd, buffer ptr: %p, size of "
662            "buffer: %zd", buffer_idx, buffer, size_of_buffer);
663
664    // The magic deleted buffer should only be 1024 bytes, but in case
665    // this changes, let's put an upper limit on the number of debug
666    // lines we'll output:
667    if (size_of_buffer <= 1024) {
668      for (int i = 0; i < size_of_buffer; ++i) {
669        if (buffer[i] != kMagicDeletedByte) {
670          RAW_LOG(ERROR, "Buffer byte %d is 0x%02x (should be 0x%02x).",
671                  i, buffer[i], kMagicDeletedByte);
672        }
673      }
674    } else {
675      RAW_LOG(ERROR, "Buffer too large to print corruption.");
676    }
677
678    const MallocBlock* b = queue_entry.block;
679    const size_t size = queue_entry.size;
680    if (queue_entry.num_deleter_pcs > 0) {
681      TracePrintf(STDERR_FILENO, "Deleted by thread %p\n",
682                  reinterpret_cast<void*>(
683                      PRINTABLE_PTHREAD(queue_entry.deleter_threadid)));
684
685      // We don't want to allocate or deallocate memory here, so we use
686      // placement-new.  It's ok that we don't destroy this, since we're
687      // just going to error-exit below anyway.  Union is for alignment.
688      union { void* alignment; char buf[sizeof(SymbolTable)]; } tablebuf;
689      SymbolTable* symbolization_table = new (tablebuf.buf) SymbolTable;
690      for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {
691        // Symbolizes the previous address of pc because pc may be in the
692        // next function.  This may happen when the function ends with
693        // a call to a function annotated noreturn (e.g. CHECK).
694        char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);
695        symbolization_table->Add(pc - 1);
696      }
697      if (FLAGS_symbolize_stacktrace)
698        symbolization_table->Symbolize();
699      for (int i = 0; i < queue_entry.num_deleter_pcs; i++) {
700        char *pc = reinterpret_cast<char*>(queue_entry.deleter_pcs[i]);
701        TracePrintf(STDERR_FILENO, "    @ %p %s\n",
702                    pc, symbolization_table->GetSymbol(pc - 1));
703      }
704    } else {
705      RAW_LOG(ERROR,
706              "Skipping the printing of the deleter's stack!  Its stack was "
707              "not found; either the corruption occurred too early in "
708              "execution to obtain a stack trace or --max_free_queue_size was "
709              "set to 0.");
710    }
711
712    RAW_LOG(FATAL,
713            "Memory was written to after being freed.  MallocBlock: %p, user "
714            "ptr: %p, size: %zd.  If you can't find the source of the error, "
715            "try using ASan (http://code.google.com/p/address-sanitizer/), "
716            "Valgrind, or Purify, or study the "
717            "output of the deleter's stack printed above.",
718            b, b->data_addr(), size);
719  }
720
721  static MallocBlock* FromRawPointer(void* p) {
722    const size_t data_offset = MallocBlock::data_offset();
723    // Find the header just before client's memory.
724    MallocBlock *mb = reinterpret_cast<MallocBlock *>(
725                reinterpret_cast<char *>(p) - data_offset);
726    // If mb->alloc_type_ is kMagicDeletedSizeT, we're not an ok pointer.
727    if (mb->alloc_type_ == kMagicDeletedSizeT) {
728      RAW_LOG(FATAL, "memory allocation bug: object at %p has been already"
729                     " deallocated; or else a word before the object has been"
730                     " corrupted (memory stomping bug)", p);
731    }
732    // If mb->offset_ is zero (common case), mb is the real header.  If
733    // mb->offset_ is non-zero, this block was allocated by memalign, and
734    // mb->offset_ is the distance backwards to the real header from mb,
735    // which is a fake header.  The following subtraction works for both zero
736    // and non-zero values.
737    return reinterpret_cast<MallocBlock *>(
738                reinterpret_cast<char *>(mb) - mb->offset_);
739  }
740  static const MallocBlock* FromRawPointer(const void* p) {
741    // const-safe version: we just cast about
742    return FromRawPointer(const_cast<void*>(p));
743  }
744
745  void Check(int type) const {
746    alloc_map_lock_.Lock();
747    CheckLocked(type);
748    alloc_map_lock_.Unlock();
749  }
750
751  static bool CheckEverything() {
752    alloc_map_lock_.Lock();
753    if (alloc_map_ != NULL)  alloc_map_->Iterate(CheckCallback, 0);
754    alloc_map_lock_.Unlock();
755    return true;  // if we get here, we're okay
756  }
757
758  static bool MemoryStats(int* blocks, size_t* total,
759                          int histogram[kMallocHistogramSize]) {
760    memset(histogram, 0, kMallocHistogramSize * sizeof(int));
761    alloc_map_lock_.Lock();
762    stats_blocks_ = 0;
763    stats_total_ = 0;
764    stats_histogram_ = histogram;
765    if (alloc_map_ != NULL) alloc_map_->Iterate(StatsCallback, 0);
766    *blocks = stats_blocks_;
767    *total = stats_total_;
768    alloc_map_lock_.Unlock();
769    return true;
770  }
771
772 private:  // helpers for CheckEverything and MemoryStats
773
774  static void CheckCallback(const void* ptr, int* type, int dummy) {
775    if ((*type & kDeallocatedTypeBit) == 0) {
776      FromRawPointer(ptr)->CheckLocked(*type);
777    }
778  }
779
780  // Accumulation variables for StatsCallback protected by alloc_map_lock_
781  static int stats_blocks_;
782  static size_t stats_total_;
783  static int* stats_histogram_;
784
785  static void StatsCallback(const void* ptr, int* type, int dummy) {
786    if ((*type & kDeallocatedTypeBit) == 0) {
787      const MallocBlock* b = FromRawPointer(ptr);
788      b->CheckLocked(*type);
789      ++stats_blocks_;
790      size_t mysize = b->size1_;
791      int entry = 0;
792      stats_total_ += mysize;
793      while (mysize) {
794        ++entry;
795        mysize >>= 1;
796      }
797      RAW_CHECK(entry < kMallocHistogramSize,
798                "kMallocHistogramSize should be at least as large as log2 "
799                "of the maximum process memory size");
800      stats_histogram_[entry] += 1;
801    }
802  }
803};
804
805void DanglingWriteChecker() {
806  // Clear out the remaining free queue to check for dangling writes.
807  MallocBlock::ProcessFreeQueue(NULL, 0, 0);
808}
809
810// ========================================================================= //
811
812const int MallocBlock::kMagicMalloc;
813const int MallocBlock::kMagicMMap;
814
815MallocBlock::AllocMap* MallocBlock::alloc_map_ = NULL;
816SpinLock MallocBlock::alloc_map_lock_(SpinLock::LINKER_INITIALIZED);
817
818FreeQueue<MallocBlockQueueEntry>* MallocBlock::free_queue_ = NULL;
819size_t MallocBlock::free_queue_size_ = 0;
820SpinLock MallocBlock::free_queue_lock_(SpinLock::LINKER_INITIALIZED);
821
822unsigned char MallocBlock::kMagicDeletedBuffer[1024];
823pthread_once_t MallocBlock::deleted_buffer_initialized_ = PTHREAD_ONCE_INIT;
824bool MallocBlock::deleted_buffer_initialized_no_pthreads_ = false;
825
826const char* const MallocBlock::kAllocName[] = {
827  "malloc",
828  "new",
829  "new []",
830  NULL,
831};
832
833const char* const MallocBlock::kDeallocName[] = {
834  "free",
835  "delete",
836  "delete []",
837  NULL,
838};
839
840int MallocBlock::stats_blocks_;
841size_t MallocBlock::stats_total_;
842int* MallocBlock::stats_histogram_;
843
844// ========================================================================= //
845
846// The following cut-down version of printf() avoids
847// using stdio or ostreams.
848// This is to guarantee no recursive calls into
849// the allocator and to bound the stack space consumed.  (The pthread
850// manager thread in linuxthreads has a very small stack,
851// so fprintf can't be called.)
852static void TracePrintf(int fd, const char *fmt, ...) {
853  char buf[64];
854  int i = 0;
855  va_list ap;
856  va_start(ap, fmt);
857  const char *p = fmt;
858  char numbuf[25];
859  numbuf[sizeof(numbuf)-1] = 0;
860  while (*p != '\0') {              // until end of format string
861    char *s = &numbuf[sizeof(numbuf)-1];
862    if (p[0] == '%' && p[1] != 0) {  // handle % formats
863      int64 l = 0;
864      unsigned long base = 0;
865      if (*++p == 's') {                            // %s
866        s = va_arg(ap, char *);
867      } else if (*p == 'l' && p[1] == 'd') {        // %ld
868        l = va_arg(ap, long);
869        base = 10;
870        p++;
871      } else if (*p == 'l' && p[1] == 'u') {        // %lu
872        l = va_arg(ap, unsigned long);
873        base = 10;
874        p++;
875      } else if (*p == 'z' && p[1] == 'u') {        // %zu
876        l = va_arg(ap, size_t);
877        base = 10;
878        p++;
879      } else if (*p == 'u') {                       // %u
880        l = va_arg(ap, unsigned int);
881        base = 10;
882      } else if (*p == 'd') {                       // %d
883        l = va_arg(ap, int);
884        base = 10;
885      } else if (*p == 'p') {                       // %p
886        l = va_arg(ap, intptr_t);
887        base = 16;
888      } else {
889        write(STDERR_FILENO, "Unimplemented TracePrintf format\n", 33);
890        write(STDERR_FILENO, p, 2);
891        write(STDERR_FILENO, "\n", 1);
892        abort();
893      }
894      p++;
895      if (base != 0) {
896        bool minus = (l < 0 && base == 10);
897        uint64 ul = minus? -l : l;
898        do {
899          *--s = "0123456789abcdef"[ul % base];
900          ul /= base;
901        } while (ul != 0);
902        if (base == 16) {
903          *--s = 'x';
904          *--s = '0';
905        } else if (minus) {
906          *--s = '-';
907        }
908      }
909    } else {                        // handle normal characters
910      *--s = *p++;
911    }
912    while (*s != 0) {
913      if (i == sizeof(buf)) {
914        write(fd, buf, i);
915        i = 0;
916      }
917      buf[i++] = *s++;
918    }
919  }
920  if (i != 0) {
921    write(fd, buf, i);
922  }
923  va_end(ap);
924}
925
926// Return the file descriptor we're writing a log to
927static int TraceFd() {
928  static int trace_fd = -1;
929  if (trace_fd == -1) {            // Open the trace file on the first call
930    trace_fd = open("/tmp/google.alloc", O_CREAT|O_TRUNC|O_WRONLY, 0666);
931    if (trace_fd == -1) {
932      trace_fd = 2;
933      TracePrintf(trace_fd,
934                  "Can't open /tmp/google.alloc.  Logging to stderr.\n");
935    }
936    // Add a header to the log.
937    TracePrintf(trace_fd, "Trace started: %lu\n",
938                static_cast<unsigned long>(time(NULL)));
939    TracePrintf(trace_fd,
940                "func\tsize\tptr\tthread_id\tstack pcs for tools/symbolize\n");
941  }
942  return trace_fd;
943}
944
945// Print the hex stack dump on a single line.   PCs are separated by tabs.
946static void TraceStack(void) {
947  void *pcs[16];
948  int n = GetStackTrace(pcs, sizeof(pcs)/sizeof(pcs[0]), 0);
949  for (int i = 0; i != n; i++) {
950    TracePrintf(TraceFd(), "\t%p", pcs[i]);
951  }
952}
953
954// This protects MALLOC_TRACE, to make sure its info is atomically written.
955static SpinLock malloc_trace_lock(SpinLock::LINKER_INITIALIZED);
956
957#define MALLOC_TRACE(name, size, addr)                                  \
958  do {                                                                  \
959    if (FLAGS_malloctrace) {                                            \
960      SpinLockHolder l(&malloc_trace_lock);                             \
961      TracePrintf(TraceFd(), "%s\t%"PRIuS"\t%p\t%"GPRIuPTHREAD,         \
962                  name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \
963      TraceStack();                                                     \
964      TracePrintf(TraceFd(), "\n");                                     \
965    }                                                                   \
966  } while (0)
967
968// ========================================================================= //
969
970// Write the characters buf[0, ..., size-1] to
971// the malloc trace buffer.
972// This function is intended for debugging,
973// and is not declared in any header file.
974// You must insert a declaration of it by hand when you need
975// to use it.
976void __malloctrace_write(const char *buf, size_t size) {
977  if (FLAGS_malloctrace) {
978    write(TraceFd(), buf, size);
979  }
980}
981
982// ========================================================================= //
983
984// General debug allocation/deallocation
985
986static inline void* DebugAllocate(size_t size, int type) {
987  MallocBlock* ptr = MallocBlock::Allocate(size, type);
988  if (ptr == NULL)  return NULL;
989  MALLOC_TRACE("malloc", size, ptr->data_addr());
990  return ptr->data_addr();
991}
992
993static inline void DebugDeallocate(void* ptr, int type) {
994  MALLOC_TRACE("free",
995               (ptr != 0 ? MallocBlock::FromRawPointer(ptr)->data_size() : 0),
996               ptr);
997  if (ptr)  MallocBlock::FromRawPointer(ptr)->Deallocate(type);
998}
999
1000// ========================================================================= //
1001
1002// The following functions may be called via MallocExtension::instance()
1003// for memory verification and statistics.
1004class DebugMallocImplementation : public TCMallocImplementation {
1005 public:
1006  virtual bool GetNumericProperty(const char* name, size_t* value) {
1007    bool result = TCMallocImplementation::GetNumericProperty(name, value);
1008    if (result && (strcmp(name, "generic.current_allocated_bytes") == 0)) {
1009      // Subtract bytes kept in the free queue
1010      size_t qsize = MallocBlock::FreeQueueSize();
1011      if (*value >= qsize) {
1012        *value -= qsize;
1013      }
1014    }
1015    return result;
1016  }
1017
1018  virtual bool VerifyNewMemory(const void* p) {
1019    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kNewType);
1020    return true;
1021  }
1022
1023  virtual bool VerifyArrayNewMemory(const void* p) {
1024    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kArrayNewType);
1025    return true;
1026  }
1027
1028  virtual bool VerifyMallocMemory(const void* p) {
1029    if (p)  MallocBlock::FromRawPointer(p)->Check(MallocBlock::kMallocType);
1030    return true;
1031  }
1032
1033  virtual bool VerifyAllMemory() {
1034    return MallocBlock::CheckEverything();
1035  }
1036
1037  virtual bool MallocMemoryStats(int* blocks, size_t* total,
1038                                 int histogram[kMallocHistogramSize]) {
1039    return MallocBlock::MemoryStats(blocks, total, histogram);
1040  }
1041
1042  virtual size_t GetEstimatedAllocatedSize(size_t size) {
1043    return size;
1044  }
1045
1046  virtual size_t GetAllocatedSize(const void* p) {
1047    if (p) {
1048      RAW_CHECK(GetOwnership(p) != MallocExtension::kNotOwned,
1049                "ptr not allocated by tcmalloc");
1050      return MallocBlock::FromRawPointer(p)->data_size();
1051    }
1052    return 0;
1053  }
1054
1055  virtual MallocExtension::Ownership GetOwnership(const void* p) {
1056    if (p) {
1057      const MallocBlock* mb = MallocBlock::FromRawPointer(p);
1058      return TCMallocImplementation::GetOwnership(mb);
1059    }
1060    return MallocExtension::kNotOwned;   // nobody owns NULL
1061  }
1062
1063  virtual void GetFreeListSizes(vector<MallocExtension::FreeListInfo>* v) {
1064    static const char* kDebugFreeQueue = "debug.free_queue";
1065
1066    TCMallocImplementation::GetFreeListSizes(v);
1067
1068    MallocExtension::FreeListInfo i;
1069    i.type = kDebugFreeQueue;
1070    i.min_object_size = 0;
1071    i.max_object_size = numeric_limits<size_t>::max();
1072    i.total_bytes_free = MallocBlock::FreeQueueSize();
1073    v->push_back(i);
1074  }
1075
1076 };
1077
1078static DebugMallocImplementation debug_malloc_implementation;
1079
1080REGISTER_MODULE_INITIALIZER(debugallocation, {
1081  // Either we or valgrind will control memory management.  We
1082  // register our extension if we're the winner. Otherwise let
1083  // Valgrind use its own malloc (so don't register our extension).
1084  if (!RunningOnValgrind()) {
1085    MallocExtension::Register(&debug_malloc_implementation);
1086  }
1087});
1088
1089REGISTER_MODULE_DESTRUCTOR(debugallocation, {
1090  if (!RunningOnValgrind()) {
1091    // When the program exits, check all blocks still in the free
1092    // queue for corruption.
1093    DanglingWriteChecker();
1094  }
1095});
1096
1097// ========================================================================= //
1098
1099// This is mostly the same a cpp_alloc in tcmalloc.cc.
1100// TODO(csilvers): change Allocate() above to call cpp_alloc, so we
1101// don't have to reproduce the logic here.  To make tc_new_mode work
1102// properly, I think we'll need to separate out the logic of throwing
1103// from the logic of calling the new-handler.
1104inline void* debug_cpp_alloc(size_t size, int new_type, bool nothrow) {
1105  for (;;) {
1106    void* p = DebugAllocate(size, new_type);
1107#ifdef PREANSINEW
1108    return p;
1109#else
1110    if (p == NULL) {  // allocation failed
1111      // Get the current new handler.  NB: this function is not
1112      // thread-safe.  We make a feeble stab at making it so here, but
1113      // this lock only protects against tcmalloc interfering with
1114      // itself, not with other libraries calling set_new_handler.
1115      std::new_handler nh;
1116      {
1117        SpinLockHolder h(&set_new_handler_lock);
1118        nh = std::set_new_handler(0);
1119        (void) std::set_new_handler(nh);
1120      }
1121#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
1122      if (nh) {
1123        // Since exceptions are disabled, we don't really know if new_handler
1124        // failed.  Assume it will abort if it fails.
1125        (*nh)();
1126        continue;
1127      }
1128      return 0;
1129#else
1130      // If no new_handler is established, the allocation failed.
1131      if (!nh) {
1132        if (nothrow) return 0;
1133        throw std::bad_alloc();
1134      }
1135      // Otherwise, try the new_handler.  If it returns, retry the
1136      // allocation.  If it throws std::bad_alloc, fail the allocation.
1137      // if it throws something else, don't interfere.
1138      try {
1139        (*nh)();
1140      } catch (const std::bad_alloc&) {
1141        if (!nothrow) throw;
1142        return p;
1143      }
1144#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
1145    } else {  // allocation success
1146      return p;
1147    }
1148#endif  // PREANSINEW
1149  }
1150}
1151
1152inline void* do_debug_malloc_or_debug_cpp_alloc(size_t size) {
1153  return tc_new_mode ? debug_cpp_alloc(size, MallocBlock::kMallocType, true)
1154                     : DebugAllocate(size, MallocBlock::kMallocType);
1155}
1156
1157// Exported routines
1158
1159extern "C" PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW {
1160  void* ptr = do_debug_malloc_or_debug_cpp_alloc(size);
1161  MallocHook::InvokeNewHook(ptr, size);
1162  return ptr;
1163}
1164
1165extern "C" PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW {
1166  MallocHook::InvokeDeleteHook(ptr);
1167  DebugDeallocate(ptr, MallocBlock::kMallocType);
1168}
1169
1170extern "C" PERFTOOLS_DLL_DECL void* tc_calloc(size_t count, size_t size) __THROW {
1171  // Overflow check
1172  const size_t total_size = count * size;
1173  if (size != 0 && total_size / size != count) return NULL;
1174
1175  void* block = do_debug_malloc_or_debug_cpp_alloc(total_size);
1176  MallocHook::InvokeNewHook(block, total_size);
1177  if (block)  memset(block, 0, total_size);
1178  return block;
1179}
1180
1181extern "C" PERFTOOLS_DLL_DECL void tc_cfree(void* ptr) __THROW {
1182  MallocHook::InvokeDeleteHook(ptr);
1183  DebugDeallocate(ptr, MallocBlock::kMallocType);
1184}
1185
1186extern "C" PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW {
1187  if (ptr == NULL) {
1188    ptr = do_debug_malloc_or_debug_cpp_alloc(size);
1189    MallocHook::InvokeNewHook(ptr, size);
1190    return ptr;
1191  }
1192  if (size == 0) {
1193    MallocHook::InvokeDeleteHook(ptr);
1194    DebugDeallocate(ptr, MallocBlock::kMallocType);
1195    return NULL;
1196  }
1197  MallocBlock* old = MallocBlock::FromRawPointer(ptr);
1198  old->Check(MallocBlock::kMallocType);
1199  MallocBlock* p = MallocBlock::Allocate(size, MallocBlock::kMallocType);
1200
1201  // If realloc fails we are to leave the old block untouched and
1202  // return null
1203  if (p == NULL)  return NULL;
1204
1205  memcpy(p->data_addr(), old->data_addr(),
1206         (old->data_size() < size) ? old->data_size() : size);
1207  MallocHook::InvokeDeleteHook(ptr);
1208  MallocHook::InvokeNewHook(p->data_addr(), size);
1209  DebugDeallocate(ptr, MallocBlock::kMallocType);
1210  MALLOC_TRACE("realloc", p->data_size(), p->data_addr());
1211  return p->data_addr();
1212}
1213
1214extern "C" PERFTOOLS_DLL_DECL void* tc_new(size_t size) {
1215  void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, false);
1216  MallocHook::InvokeNewHook(ptr, size);
1217  if (ptr == NULL) {
1218    RAW_LOG(FATAL, "Unable to allocate %"PRIuS" bytes: new failed.", size);
1219  }
1220  return ptr;
1221}
1222
1223extern "C" PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothrow_t&) __THROW {
1224  void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, true);
1225  MallocHook::InvokeNewHook(ptr, size);
1226  return ptr;
1227}
1228
1229extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW {
1230  MallocHook::InvokeDeleteHook(p);
1231  DebugDeallocate(p, MallocBlock::kNewType);
1232}
1233
1234// Some STL implementations explicitly invoke this.
1235// It is completely equivalent to a normal delete (delete never throws).
1236extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) __THROW {
1237  MallocHook::InvokeDeleteHook(p);
1238  DebugDeallocate(p, MallocBlock::kNewType);
1239}
1240
1241extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size) {
1242  void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, false);
1243  MallocHook::InvokeNewHook(ptr, size);
1244  if (ptr == NULL) {
1245    RAW_LOG(FATAL, "Unable to allocate %"PRIuS" bytes: new[] failed.", size);
1246  }
1247  return ptr;
1248}
1249
1250extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::nothrow_t&)
1251    __THROW {
1252  void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, true);
1253  MallocHook::InvokeNewHook(ptr, size);
1254  return ptr;
1255}
1256
1257extern "C" PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW {
1258  MallocHook::InvokeDeleteHook(p);
1259  DebugDeallocate(p, MallocBlock::kArrayNewType);
1260}
1261
1262// Some STL implementations explicitly invoke this.
1263// It is completely equivalent to a normal delete (delete never throws).
1264extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::nothrow_t&) __THROW {
1265  MallocHook::InvokeDeleteHook(p);
1266  DebugDeallocate(p, MallocBlock::kArrayNewType);
1267}
1268
1269// Round "value" up to next "alignment" boundary.
1270// Requires that "alignment" be a power of two.
1271static intptr_t RoundUp(intptr_t value, intptr_t alignment) {
1272  return (value + alignment - 1) & ~(alignment - 1);
1273}
1274
1275// This is mostly the same as do_memalign in tcmalloc.cc.
1276static void *do_debug_memalign(size_t alignment, size_t size) {
1277  // Allocate >= size bytes aligned on "alignment" boundary
1278  // "alignment" is a power of two.
1279  void *p = 0;
1280  RAW_CHECK((alignment & (alignment-1)) == 0, "must be power of two");
1281  const size_t data_offset = MallocBlock::data_offset();
1282  // Allocate "alignment-1" extra bytes to ensure alignment is possible, and
1283  // a further data_offset bytes for an additional fake header.
1284  size_t extra_bytes = data_offset + alignment - 1;
1285  if (size + extra_bytes < size) return NULL;         // Overflow
1286  p = DebugAllocate(size + extra_bytes, MallocBlock::kMallocType);
1287  if (p != 0) {
1288    intptr_t orig_p = reinterpret_cast<intptr_t>(p);
1289    // Leave data_offset bytes for fake header, and round up to meet
1290    // alignment.
1291    p = reinterpret_cast<void *>(RoundUp(orig_p + data_offset, alignment));
1292    // Create a fake header block with an offset_ that points back to the
1293    // real header.  FromRawPointer uses this value.
1294    MallocBlock *fake_hdr = reinterpret_cast<MallocBlock *>(
1295                reinterpret_cast<char *>(p) - data_offset);
1296    // offset_ is distance between real and fake headers.
1297    // p is now end of fake header (beginning of client area),
1298    // and orig_p is the end of the real header, so offset_
1299    // is their difference.
1300    fake_hdr->set_offset(reinterpret_cast<intptr_t>(p) - orig_p);
1301  }
1302  return p;
1303}
1304
1305// This is mostly the same as cpp_memalign in tcmalloc.cc.
1306static void* debug_cpp_memalign(size_t align, size_t size) {
1307  for (;;) {
1308    void* p = do_debug_memalign(align, size);
1309#ifdef PREANSINEW
1310    return p;
1311#else
1312    if (p == NULL) {  // allocation failed
1313      // Get the current new handler.  NB: this function is not
1314      // thread-safe.  We make a feeble stab at making it so here, but
1315      // this lock only protects against tcmalloc interfering with
1316      // itself, not with other libraries calling set_new_handler.
1317      std::new_handler nh;
1318      {
1319        SpinLockHolder h(&set_new_handler_lock);
1320        nh = std::set_new_handler(0);
1321        (void) std::set_new_handler(nh);
1322      }
1323#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
1324      if (nh) {
1325        // Since exceptions are disabled, we don't really know if new_handler
1326        // failed.  Assume it will abort if it fails.
1327        (*nh)();
1328        continue;
1329      }
1330      return 0;
1331#else
1332      // If no new_handler is established, the allocation failed.
1333      if (!nh)
1334        return 0;
1335
1336      // Otherwise, try the new_handler.  If it returns, retry the
1337      // allocation.  If it throws std::bad_alloc, fail the allocation.
1338      // if it throws something else, don't interfere.
1339      try {
1340        (*nh)();
1341      } catch (const std::bad_alloc&) {
1342        return p;
1343      }
1344#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
1345    } else {  // allocation success
1346      return p;
1347    }
1348#endif  // PREANSINEW
1349  }
1350}
1351
1352inline void* do_debug_memalign_or_debug_cpp_memalign(size_t align,
1353                                                     size_t size) {
1354  return tc_new_mode ? debug_cpp_memalign(align, size)
1355                     : do_debug_memalign(align, size);
1356}
1357
1358extern "C" PERFTOOLS_DLL_DECL void* tc_memalign(size_t align, size_t size) __THROW {
1359  void *p = do_debug_memalign_or_debug_cpp_memalign(align, size);
1360  MallocHook::InvokeNewHook(p, size);
1361  return p;
1362}
1363
1364// Implementation taken from tcmalloc/tcmalloc.cc
1365extern "C" PERFTOOLS_DLL_DECL int tc_posix_memalign(void** result_ptr, size_t align, size_t size)
1366    __THROW {
1367  if (((align % sizeof(void*)) != 0) ||
1368      ((align & (align - 1)) != 0) ||
1369      (align == 0)) {
1370    return EINVAL;
1371  }
1372
1373  void* result = do_debug_memalign_or_debug_cpp_memalign(align, size);
1374  MallocHook::InvokeNewHook(result, size);
1375  if (result == NULL) {
1376    return ENOMEM;
1377  } else {
1378    *result_ptr = result;
1379    return 0;
1380  }
1381}
1382
1383extern "C" PERFTOOLS_DLL_DECL void* tc_valloc(size_t size) __THROW {
1384  // Allocate >= size bytes starting on a page boundary
1385  void *p = do_debug_memalign_or_debug_cpp_memalign(getpagesize(), size);
1386  MallocHook::InvokeNewHook(p, size);
1387  return p;
1388}
1389
1390extern "C" PERFTOOLS_DLL_DECL void* tc_pvalloc(size_t size) __THROW {
1391  // Round size up to a multiple of pages
1392  // then allocate memory on a page boundary
1393  int pagesize = getpagesize();
1394  size = RoundUp(size, pagesize);
1395  if (size == 0) {     // pvalloc(0) should allocate one page, according to
1396    size = pagesize;   // http://man.free4web.biz/man3/libmpatrol.3.html
1397  }
1398  void *p = do_debug_memalign_or_debug_cpp_memalign(pagesize, size);
1399  MallocHook::InvokeNewHook(p, size);
1400  return p;
1401}
1402
1403// malloc_stats just falls through to the base implementation.
1404extern "C" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) __THROW {
1405  BASE_MALLOC_STATS();
1406}
1407
1408extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW {
1409  return BASE_MALLOPT(cmd, value);
1410}
1411
1412#ifdef HAVE_STRUCT_MALLINFO
1413extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW {
1414  return BASE_MALLINFO();
1415}
1416#endif
1417
1418extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW {
1419  return MallocExtension::instance()->GetAllocatedSize(ptr);
1420}
1421