// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// ---
// Author: Maxim Lifantsev (with design ideas by Sanjay Ghemawat)
//
//
// Module for detecing heap (memory) leaks.
//
// For full(er) information, see docs/heap_checker.html
//
// This module can be linked into programs with
// no slowdown caused by this unless you activate the leak-checker:
//
//    1. Set the environment variable HEAPCHEK to _type_ before
//       running the program.
//
// _type_ is usually "normal" but can also be "minimal", "strict", or
// "draconian".  (See the html file for other options, like 'local'.)
//
// After that, just run your binary.  If the heap-checker detects
// a memory leak at program-exit, it will print instructions on how
// to track down the leak.

#ifndef BASE_HEAP_CHECKER_H_
#define BASE_HEAP_CHECKER_H_

#include <sys/types.h>  // for size_t
// I can't #include config.h in this public API file, but I should
// really use configure (and make malloc_extension.h a .in file) to
// figure out if the system has stdint.h or not.  But I'm lazy, so
// for now I'm assuming it's a problem only with MSVC.
#ifndef _MSC_VER
#include <stdint.h>     // for uintptr_t
#endif
#include <stdarg.h>     // for va_list
#include <vector>

// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef PERFTOOLS_DLL_DECL
# ifdef _WIN32
#   define PERFTOOLS_DLL_DECL  __declspec(dllimport)
# else
#   define PERFTOOLS_DLL_DECL
# endif
#endif


// The class is thread-safe with respect to all the provided static methods,
// as well as HeapLeakChecker objects: they can be accessed by multiple threads.
class PERFTOOLS_DLL_DECL HeapLeakChecker {
 public:

  // ----------------------------------------------------------------------- //
  // Static functions for working with (whole-program) leak checking.

  // If heap leak checking is currently active in some mode
  // e.g. if leak checking was started (and is still active now)
  // due to HEAPCHECK=... defined in the environment.
  // The return value reflects iff HeapLeakChecker objects manually
  // constructed right now will be doing leak checking or nothing.
  // Note that we can go from active to inactive state during InitGoogle()
  // if FLAGS_heap_check gets set to "" by some code before/during InitGoogle().
  static bool IsActive();

  // Return pointer to the whole-program checker if it has been created
  // and NULL otherwise.
  // Once GlobalChecker() returns non-NULL that object will not disappear and
  // will be returned by all later GlobalChecker calls.
  // This is mainly to access BytesLeaked() and ObjectsLeaked() (see below)
  // for the whole-program checker after one calls NoGlobalLeaks()
  // or similar and gets false.
  static HeapLeakChecker* GlobalChecker();

  // Do whole-program leak check now (if it was activated for this binary);
  // return false only if it was activated and has failed.
  // The mode of the check is controlled by the command-line flags.
  // This method can be called repeatedly.
  // Things like GlobalChecker()->SameHeap() can also be called explicitly
  // to do the desired flavor of the check.
  static bool NoGlobalLeaks();

  // If whole-program checker if active,
  // cancel its automatic execution after main() exits.
  // This requires that some leak check (e.g. NoGlobalLeaks())
  // has been called at least once on the whole-program checker.
  static void CancelGlobalCheck();

  // ----------------------------------------------------------------------- //
  // Non-static functions for starting and doing leak checking.

  // Start checking and name the leak check performed.
  // The name is used in naming dumped profiles
  // and needs to be unique only within your binary.
  // It must also be a string that can be a part of a file name,
  // in particular not contain path expressions.
  explicit HeapLeakChecker(const char *name);

  // Destructor (verifies that some *NoLeaks or *SameHeap method
  // has been called at least once).
  ~HeapLeakChecker();

  // These used to be different but are all the same now: they return
  // true iff all memory allocated since this HeapLeakChecker object
  // was constructor is still reachable from global state.
  //
  // Because we fork to convert addresses to symbol-names, and forking
  // is not thread-safe, and we may be called in a threaded context,
  // we do not try to symbolize addresses when called manually.
  bool NoLeaks() { return DoNoLeaks(DO_NOT_SYMBOLIZE); }

  // These forms are obsolete; use NoLeaks() instead.
  // TODO(csilvers): mark as DEPRECATED.
  bool QuickNoLeaks()  { return NoLeaks(); }
  bool BriefNoLeaks()  { return NoLeaks(); }
  bool SameHeap()      { return NoLeaks(); }
  bool QuickSameHeap() { return NoLeaks(); }
  bool BriefSameHeap() { return NoLeaks(); }

  // Detailed information about the number of leaked bytes and objects
  // (both of these can be negative as well).
  // These are available only after a *SameHeap or *NoLeaks
  // method has been called.
  // Note that it's possible for both of these to be zero
  // while SameHeap() or NoLeaks() returned false in case
  // of a heap state change that is significant
  // but preserves the byte and object counts.
  ssize_t BytesLeaked() const;
  ssize_t ObjectsLeaked() const;

  // ----------------------------------------------------------------------- //
  // Static helpers to make us ignore certain leaks.

  // Scoped helper class.  Should be allocated on the stack inside a
  // block of code.  Any heap allocations done in the code block
  // covered by the scoped object (including in nested function calls
  // done by the code block) will not be reported as leaks.  This is
  // the recommended replacement for the GetDisableChecksStart() and
  // DisableChecksToHereFrom() routines below.
  //
  // Example:
  //   void Foo() {
  //     HeapLeakChecker::Disabler disabler;
  //     ... code that allocates objects whose leaks should be ignored ...
  //   }
  //
  // REQUIRES: Destructor runs in same thread as constructor
  class Disabler {
   public:
    Disabler();
    ~Disabler();
   private:
    Disabler(const Disabler&);        // disallow copy
    void operator=(const Disabler&);  // and assign
  };

  // Ignore an object located at 'ptr' (can go at the start or into the object)
  // as well as all heap objects (transitively) referenced from it for the
  // purposes of heap leak checking. Returns 'ptr' so that one can write
  //   static T* obj = IgnoreObject(new T(...));
  //
  // If 'ptr' does not point to an active allocated object at the time of this
  // call, it is ignored; but if it does, the object must not get deleted from
  // the heap later on.
  //
  // See also HiddenPointer, below, if you need to prevent a pointer from
  // being traversed by the heap checker but do not wish to transitively
  // whitelist objects referenced through it.
  template <typename T>
  static T* IgnoreObject(T* ptr) {
    DoIgnoreObject(static_cast<const void*>(const_cast<const T*>(ptr)));
    return ptr;
  }

  // Undo what an earlier IgnoreObject() call promised and asked to do.
  // At the time of this call 'ptr' must point at or inside of an active
  // allocated object which was previously registered with IgnoreObject().
  static void UnIgnoreObject(const void* ptr);

  // ----------------------------------------------------------------------- //
  // Internal types defined in .cc

  class Allocator;
  struct RangeValue;

 private:

  // ----------------------------------------------------------------------- //
  // Various helpers

  // Create the name of the heap profile file.
  // Should be deleted via Allocator::Free().
  char* MakeProfileNameLocked();

  // Helper for constructors
  void Create(const char *name, bool make_start_snapshot);

  enum ShouldSymbolize { SYMBOLIZE, DO_NOT_SYMBOLIZE };

  // Helper for *NoLeaks and *SameHeap
  bool DoNoLeaks(ShouldSymbolize should_symbolize);

  // Helper for NoGlobalLeaks, also called by the global destructor.
  static bool NoGlobalLeaksMaybeSymbolize(ShouldSymbolize should_symbolize);

  // These used to be public, but they are now deprecated.
  // Will remove entirely when all internal uses are fixed.
  // In the meantime, use friendship so the unittest can still test them.
  static void* GetDisableChecksStart();
  static void DisableChecksToHereFrom(const void* start_address);
  static void DisableChecksIn(const char* pattern);
  friend void RangeDisabledLeaks();
  friend void NamedTwoDisabledLeaks();
  friend void* RunNamedDisabledLeaks(void*);
  friend void TestHeapLeakCheckerNamedDisabling();

  // Actually implements IgnoreObject().
  static void DoIgnoreObject(const void* ptr);

  // Disable checks based on stack trace entry at a depth <=
  // max_depth.  Used to hide allocations done inside some special
  // libraries.
  static void DisableChecksFromToLocked(const void* start_address,
                                        const void* end_address,
                                        int max_depth);

  // Helper for DoNoLeaks to ignore all objects reachable from all live data
  static void IgnoreAllLiveObjectsLocked(const void* self_stack_top);

  // Callback we pass to TCMalloc_ListAllProcessThreads (see thread_lister.h)
  // that is invoked when all threads of our process are found and stopped.
  // The call back does the things needed to ignore live data reachable from
  // thread stacks and registers for all our threads
  // as well as do other global-live-data ignoring
  // (via IgnoreNonThreadLiveObjectsLocked)
  // during the quiet state of all threads being stopped.
  // For the argument meaning see the comment by TCMalloc_ListAllProcessThreads.
  // Here we only use num_threads and thread_pids, that TCMalloc_ListAllProcessThreads
  // fills for us with the number and pids of all the threads of our process
  // it found and attached to.
  static int IgnoreLiveThreadsLocked(void* parameter,
                                     int num_threads,
                                     pid_t* thread_pids,
                                     va_list ap);

  // Helper for IgnoreAllLiveObjectsLocked and IgnoreLiveThreadsLocked
  // that we prefer to execute from IgnoreLiveThreadsLocked
  // while all threads are stopped.
  // This helper does live object discovery and ignoring
  // for all objects that are reachable from everything
  // not related to thread stacks and registers.
  static void IgnoreNonThreadLiveObjectsLocked();

  // Helper for IgnoreNonThreadLiveObjectsLocked and IgnoreLiveThreadsLocked
  // to discover and ignore all heap objects
  // reachable from currently considered live objects
  // (live_objects static global variable in out .cc file).
  // "name", "name2" are two strings that we print one after another
  // in a debug message to describe what kind of live object sources
  // are being used.
  static void IgnoreLiveObjectsLocked(const char* name, const char* name2);

  // Do the overall whole-program heap leak check if needed;
  // returns true when did the leak check.
  static bool DoMainHeapCheck();

  // Type of task for UseProcMapsLocked
  enum ProcMapsTask {
    RECORD_GLOBAL_DATA,
    DISABLE_LIBRARY_ALLOCS
  };

  // Success/Error Return codes for UseProcMapsLocked.
  enum ProcMapsResult {
    PROC_MAPS_USED,
    CANT_OPEN_PROC_MAPS,
    NO_SHARED_LIBS_IN_PROC_MAPS
  };

  // Read /proc/self/maps, parse it, and do the 'proc_maps_task' for each line.
  static ProcMapsResult UseProcMapsLocked(ProcMapsTask proc_maps_task);

  // A ProcMapsTask to disable allocations from 'library'
  // that is mapped to [start_address..end_address)
  // (only if library is a certain system library).
  static void DisableLibraryAllocsLocked(const char* library,
                                         uintptr_t start_address,
                                         uintptr_t end_address);

  // Return true iff "*ptr" points to a heap object
  // ("*ptr" can point at the start or inside of a heap object
  //  so that this works e.g. for pointers to C++ arrays, C++ strings,
  //  multiple-inherited objects, or pointers to members).
  // We also fill *object_size for this object then
  // and we move "*ptr" to point to the very start of the heap object.
  static inline bool HaveOnHeapLocked(const void** ptr, size_t* object_size);

  // Helper to shutdown heap leak checker when it's not needed
  // or can't function properly.
  static void TurnItselfOffLocked();

  // Internally-used c-tor to start whole-executable checking.
  HeapLeakChecker();

  // ----------------------------------------------------------------------- //
  // Friends and externally accessed helpers.

  // Helper for VerifyHeapProfileTableStackGet in the unittest
  // to get the recorded allocation caller for ptr,
  // which must be a heap object.
  static const void* GetAllocCaller(void* ptr);
  friend void VerifyHeapProfileTableStackGet();

  // This gets to execute before constructors for all global objects
  static void BeforeConstructorsLocked();
  friend void HeapLeakChecker_BeforeConstructors();

  // This gets to execute after destructors for all global objects
  friend void HeapLeakChecker_AfterDestructors();

  // Full starting of recommended whole-program checking.
  friend void HeapLeakChecker_InternalInitStart();

  // Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially
  // calls DoMainHeapCheck
  friend void HeapLeakChecker_RunHeapCleanups();

  // ----------------------------------------------------------------------- //
  // Member data.

  class SpinLock* lock_;  // to make HeapLeakChecker objects thread-safe
  const char* name_;  // our remembered name (we own it)
                      // NULL means this leak checker is a noop

  // Snapshot taken when the checker was created.  May be NULL
  // for the global heap checker object.  We use void* instead of
  // HeapProfileTable::Snapshot* to avoid including heap-profile-table.h.
  void* start_snapshot_;

  bool has_checked_;  // if we have done the leak check, so these are ready:
  ssize_t inuse_bytes_increase_;  // bytes-in-use increase for this checker
  ssize_t inuse_allocs_increase_;  // allocations-in-use increase
                                   // for this checker
  bool keep_profiles_;  // iff we should keep the heap profiles we've made

  // ----------------------------------------------------------------------- //

  // Disallow "evil" constructors.
  HeapLeakChecker(const HeapLeakChecker&);
  void operator=(const HeapLeakChecker&);
};


// Holds a pointer that will not be traversed by the heap checker.
// Contrast with HeapLeakChecker::IgnoreObject(o), in which o and
// all objects reachable from o are ignored by the heap checker.
template <class T>
class HiddenPointer {
 public:
  explicit HiddenPointer(T* t)
      : masked_t_(reinterpret_cast<uintptr_t>(t) ^ kHideMask) {
  }
  // Returns unhidden pointer.  Be careful where you save the result.
  T* get() const { return reinterpret_cast<T*>(masked_t_ ^ kHideMask); }

 private:
  // Arbitrary value, but not such that xor'ing with it is likely
  // to map one valid pointer to another valid pointer:
  static const uintptr_t kHideMask =
      static_cast<uintptr_t>(0xF03A5F7BF03A5F7Bll);
  uintptr_t masked_t_;
};

// A class that exists solely to run its destructor.  This class should not be
// used directly, but instead by the REGISTER_HEAPCHECK_CLEANUP macro below.
class PERFTOOLS_DLL_DECL HeapCleaner {
 public:
  typedef void (*void_function)(void);
  HeapCleaner(void_function f);
  static void RunHeapCleanups();
 private:
  static std::vector<void_function>* heap_cleanups_;
};

// A macro to declare module heap check cleanup tasks
// (they run only if we are doing heap leak checking.)
// 'body' should be the cleanup code to run.  'name' doesn't matter,
// but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls.
#define REGISTER_HEAPCHECK_CLEANUP(name, body)  \
  namespace { \
  void heapcheck_cleanup_##name() { body; } \
  static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \
  }

#endif  // BASE_HEAP_CHECKER_H_
