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: Maxim Lifantsev (with design ideas by Sanjay Ghemawat)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Module for detecing heap (memory) leaks.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For full(er) information, see doc/heap_checker.html
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This module can be linked into programs with
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// no slowdown caused by this unless you activate the leak-checker:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    1. Set the environment variable HEAPCHEK to _type_ before
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       running the program.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// _type_ is usually "normal" but can also be "minimal", "strict", or
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "draconian".  (See the html file for other options, like 'local'.)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After that, just run your binary.  If the heap-checker detects
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a memory leak at program-exit, it will print instructions on how
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to track down the leak.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_HEAP_CHECKER_H_
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_HEAP_CHECKER_H_
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>  // for size_t
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// I can't #include config.h in this public API file, but I should
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// really use configure (and make malloc_extension.h a .in file) to
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// figure out if the system has stdint.h or not.  But I'm lazy, so
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for now I'm assuming it's a problem only with MSVC.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _MSC_VER
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdint.h>     // for uintptr_t
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>     // for va_list
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Annoying stuff for windows -- makes sure clients can import these functions
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PERFTOOLS_DLL_DECL
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ifdef _WIN32
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# else
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#   define PERFTOOLS_DLL_DECL
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The class is thread-safe with respect to all the provided static methods,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as well as HeapLeakChecker objects: they can be accessed by multiple threads.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PERFTOOLS_DLL_DECL HeapLeakChecker {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ----------------------------------------------------------------------- //
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Static functions for working with (whole-program) leak checking.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If heap leak checking is currently active in some mode
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // e.g. if leak checking was started (and is still active now)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // due to HEAPCHECK=... defined in the environment.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The return value reflects iff HeapLeakChecker objects manually
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // constructed right now will be doing leak checking or nothing.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that we can go from active to inactive state during InitGoogle()
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if FLAGS_heap_check gets set to "" by some code before/during InitGoogle().
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsActive();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return pointer to the whole-program checker if it has been created
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and NULL otherwise.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once GlobalChecker() returns non-NULL that object will not disappear and
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be returned by all later GlobalChecker calls.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is mainly to access BytesLeaked() and ObjectsLeaked() (see below)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the whole-program checker after one calls NoGlobalLeaks()
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or similar and gets false.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HeapLeakChecker* GlobalChecker();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do whole-program leak check now (if it was activated for this binary);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return false only if it was activated and has failed.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mode of the check is controlled by the command-line flags.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method can be called repeatedly.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Things like GlobalChecker()->SameHeap() can also be called explicitly
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to do the desired flavor of the check.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool NoGlobalLeaks();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If whole-program checker if active,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cancel its automatic execution after main() exits.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This requires that some leak check (e.g. NoGlobalLeaks())
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has been called at least once on the whole-program checker.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void CancelGlobalCheck();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ----------------------------------------------------------------------- //
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-static functions for starting and doing leak checking.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start checking and name the leak check performed.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The name is used in naming dumped profiles
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and needs to be unique only within your binary.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It must also be a string that can be a part of a file name,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in particular not contain path expressions.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit HeapLeakChecker(const char *name);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destructor (verifies that some *NoLeaks or *SameHeap method
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has been called at least once).
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~HeapLeakChecker();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These used to be different but are all the same now: they return
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // true iff all memory allocated since this HeapLeakChecker object
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was constructor is still reachable from global state.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because we fork to convert addresses to symbol-names, and forking
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is not thread-safe, and we may be called in a threaded context,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we do not try to symbolize addresses when called manually.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool NoLeaks() { return DoNoLeaks(DO_NOT_SYMBOLIZE); }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These forms are obsolete; use NoLeaks() instead.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(csilvers): mark as DEPRECATED.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool QuickNoLeaks()  { return NoLeaks(); }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool BriefNoLeaks()  { return NoLeaks(); }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SameHeap()      { return NoLeaks(); }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool QuickSameHeap() { return NoLeaks(); }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool BriefSameHeap() { return NoLeaks(); }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Detailed information about the number of leaked bytes and objects
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (both of these can be negative as well).
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These are available only after a *SameHeap or *NoLeaks
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // method has been called.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that it's possible for both of these to be zero
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // while SameHeap() or NoLeaks() returned false in case
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of a heap state change that is significant
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but preserves the byte and object counts.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssize_t BytesLeaked() const;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssize_t ObjectsLeaked() const;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ----------------------------------------------------------------------- //
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Static helpers to make us ignore certain leaks.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Scoped helper class.  Should be allocated on the stack inside a
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // block of code.  Any heap allocations done in the code block
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // covered by the scoped object (including in nested function calls
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // done by the code block) will not be reported as leaks.  This is
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the recommended replacement for the GetDisableChecksStart() and
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DisableChecksToHereFrom() routines below.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Example:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   void Foo() {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     HeapLeakChecker::Disabler disabler;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     ... code that allocates objects whose leaks should be ignored ...
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // REQUIRES: Destructor runs in same thread as constructor
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Disabler {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Disabler();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~Disabler();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Disabler(const Disabler&);        // disallow copy
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void operator=(const Disabler&);  // and assign
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignore an object located at 'ptr' (can go at the start or into the object)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as well as all heap objects (transitively) referenced from it for the
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // purposes of heap leak checking. Returns 'ptr' so that one can write
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   static T* obj = IgnoreObject(new T(...));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If 'ptr' does not point to an active allocated object at the time of this
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // call, it is ignored; but if it does, the object must not get deleted from
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the heap later on.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See also HiddenPointer, below, if you need to prevent a pointer from
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // being traversed by the heap checker but do not wish to transitively
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whitelist objects referenced through it.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename T>
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static T* IgnoreObject(T* ptr) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DoIgnoreObject(static_cast<const void*>(const_cast<const T*>(ptr)));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ptr;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Undo what an earlier IgnoreObject() call promised and asked to do.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At the time of this call 'ptr' must point at or inside of an active
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allocated object which was previously registered with IgnoreObject().
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void UnIgnoreObject(const void* ptr);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ----------------------------------------------------------------------- //
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Internal types defined in .cc
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Allocator;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct RangeValue;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ----------------------------------------------------------------------- //
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Various helpers
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the name of the heap profile file.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should be deleted via Allocator::Free().
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* MakeProfileNameLocked();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper for constructors
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Create(const char *name, bool make_start_snapshot);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE };
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper for *NoLeaks and *SameHeap
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DoNoLeaks(ShouldSymbolize should_symbolize);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper for NoGlobalLeaks, also called by the global destructor.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool NoGlobalLeaksMaybeSymbolize(ShouldSymbolize should_symbolize);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These used to be public, but they are now deprecated.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will remove entirely when all internal uses are fixed.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In the meantime, use friendship so the unittest can still test them.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void* GetDisableChecksStart();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DisableChecksToHereFrom(const void* start_address);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DisableChecksIn(const char* pattern);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void RangeDisabledLeaks();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void NamedTwoDisabledLeaks();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void* RunNamedDisabledLeaks(void*);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void TestHeapLeakCheckerNamedDisabling();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(csilvers): remove this one, at least
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend int main(int, char**);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Actually implements IgnoreObject().
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DoIgnoreObject(const void* ptr);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable checks based on stack trace entry at a depth <=
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // max_depth.  Used to hide allocations done inside some special
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // libraries.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DisableChecksFromToLocked(const void* start_address,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const void* end_address,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int max_depth);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper for DoNoLeaks to ignore all objects reachable from all live data
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void IgnoreAllLiveObjectsLocked(const void* self_stack_top);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback we pass to ListAllProcessThreads (see thread_lister.h)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that is invoked when all threads of our process are found and stopped.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The call back does the things needed to ignore live data reachable from
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread stacks and registers for all our threads
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as well as do other global-live-data ignoring
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (via IgnoreNonThreadLiveObjectsLocked)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // during the quiet state of all threads being stopped.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For the argument meaning see the comment by ListAllProcessThreads.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Here we only use num_threads and thread_pids, that ListAllProcessThreads
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fills for us with the number and pids of all the threads of our process
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it found and attached to.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int IgnoreLiveThreadsLocked(void* parameter,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int num_threads,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     pid_t* thread_pids,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     va_list ap);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper for IgnoreAllLiveObjectsLocked and IgnoreLiveThreadsLocked
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that we prefer to execute from IgnoreLiveThreadsLocked
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // while all threads are stopped.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This helper does live object discovery and ignoring
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for all objects that are reachable from everything
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not related to thread stacks and registers.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void IgnoreNonThreadLiveObjectsLocked();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to discover and ignore all heap objects
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reachable from currently considered live objects
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (live_objects static global variable in out .cc file).
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "name", "name2" are two strings that we print one after another
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in a debug message to describe what kind of live object sources
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are being used.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void IgnoreLiveObjectsLocked(const char* name, const char* name2);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do the overall whole-program heap leak check if needed;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returns true when did the leak check.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool DoMainHeapCheck();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Type of task for UseProcMapsLocked
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ProcMapsTask {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RECORD_GLOBAL_DATA,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISABLE_LIBRARY_ALLOCS
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Success/Error Return codes for UseProcMapsLocked.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ProcMapsResult {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PROC_MAPS_USED,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CANT_OPEN_PROC_MAPS,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NO_SHARED_LIBS_IN_PROC_MAPS
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read /proc/self/maps, parse it, and do the 'proc_maps_task' for each line.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProcMapsResult UseProcMapsLocked(ProcMapsTask proc_maps_task);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A ProcMapsTask to disable allocations from 'library'
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that is mapped to [start_address..end_address)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (only if library is a certain system library).
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DisableLibraryAllocsLocked(const char* library,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         uintptr_t start_address,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         uintptr_t end_address);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return true iff "*ptr" points to a heap object
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ("*ptr" can point at the start or inside of a heap object
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  so that this works e.g. for pointers to C++ arrays, C++ strings,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  multiple-inherited objects, or pointers to members).
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We also fill *object_size for this object then
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and we move "*ptr" to point to the very start of the heap object.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static inline bool HaveOnHeapLocked(const void** ptr, size_t* object_size);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper to shutdown heap leak checker when it's not needed
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or can't function properly.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void TurnItselfOffLocked();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Internally-used c-tor to start whole-executable checking.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeapLeakChecker();
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ----------------------------------------------------------------------- //
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Friends and externally accessed helpers.
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper for VerifyHeapProfileTableStackGet in the unittest
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to get the recorded allocation caller for ptr,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which must be a heap object.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const void* GetAllocCaller(void* ptr);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void VerifyHeapProfileTableStackGet();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This gets to execute before constructors for all global objects
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void BeforeConstructorsLocked();
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void HeapLeakChecker_BeforeConstructors();
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This gets to execute after destructors for all global objects
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void HeapLeakChecker_AfterDestructors();
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Full starting of recommended whole-program checking.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void HeapLeakChecker_InternalInitStart();
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calls DoMainHeapCheck
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend void HeapLeakChecker_RunHeapCleanups();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ----------------------------------------------------------------------- //
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Member data.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class SpinLock* lock_;  // to make HeapLeakChecker objects thread-safe
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name_;  // our remembered name (we own it)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      // NULL means this leak checker is a noop
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Snapshot taken when the checker was created.  May be NULL
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the global heap checker object.  We use void* instead of
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HeapProfileTable::Snapshot* to avoid including heap-profile-table.h.
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* start_snapshot_;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_checked_;  // if we have done the leak check, so these are ready:
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssize_t inuse_bytes_increase_;  // bytes-in-use increase for this checker
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssize_t inuse_allocs_increase_;  // allocations-in-use increase
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   // for this checker
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool keep_profiles_;  // iff we should keep the heap profiles we've made
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ----------------------------------------------------------------------- //
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disallow "evil" constructors.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeapLeakChecker(const HeapLeakChecker&);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void operator=(const HeapLeakChecker&);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Holds a pointer that will not be traversed by the heap checker.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Contrast with HeapLeakChecker::IgnoreObject(o), in which o and
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// all objects reachable from o are ignored by the heap checker.
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T>
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HiddenPointer {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit HiddenPointer(T* t)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : masked_t_(reinterpret_cast<uintptr_t>(t) ^ kHideMask) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns unhidden pointer.  Be careful where you save the result.
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T* get() const { return reinterpret_cast<T*>(masked_t_ ^ kHideMask); }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Arbitrary value, but not such that xor'ing with it is likely
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to map one valid pointer to another valid pointer:
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uintptr_t kHideMask =
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<uintptr_t>(0xF03A5F7BF03A5F7Bll);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uintptr_t masked_t_;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class that exists solely to run its destructor.  This class should not be
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used directly, but instead by the REGISTER_HEAPCHECK_CLEANUP macro below.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PERFTOOLS_DLL_DECL HeapCleaner {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef void (*void_function)(void);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HeapCleaner(void_function f);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunHeapCleanups();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::vector<void_function>* heap_cleanups_;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A macro to declare module heap check cleanup tasks
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (they run only if we are doing heap leak checking.)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 'body' should be the cleanup code to run.  'name' doesn't matter,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REGISTER_HEAPCHECK_CLEANUP(name, body)  \
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  namespace { \
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void heapcheck_cleanup_##name() { body; } \
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_HEAP_CHECKER_H_
425