// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Activity tracking provides a low-overhead method of collecting information
// about the state of the application for analysis both while it is running
// and after it has terminated unexpectedly. Its primary purpose is to help
// locate reasons the browser becomes unresponsive by providing insight into
// what all the various threads and processes are (or were) doing.

#ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_
#define BASE_DEBUG_ACTIVITY_TRACKER_H_

// std::atomic is undesired due to performance issues when used as global
// variables. There are no such instances here. This module uses the
// PersistentMemoryAllocator which also uses std::atomic and is written
// by the same author.
#include <atomic>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/atomicops.h"
#include "base/base_export.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/location.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/persistent_memory_allocator.h"
#include "base/process/process_handle.h"
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_local_storage.h"

namespace base {

struct PendingTask;

class FilePath;
class Lock;
class PlatformThreadHandle;
class Process;
class WaitableEvent;

namespace debug {

class ThreadActivityTracker;


enum : int {
  // The maximum number of call-stack addresses stored per activity. This
  // cannot be changed without also changing the version number of the
  // structure. See kTypeIdActivityTracker in GlobalActivityTracker.
  kActivityCallStackSize = 10,
};

// A class for keeping all information needed to verify that a structure is
// associated with a given process.
struct OwningProcess {
  OwningProcess();
  ~OwningProcess();

  // Initializes structure with the current process id and the current time.
  // These can uniquely identify a process. A unique non-zero data_id will be
  // set making it possible to tell using atomic reads if the data has changed.
  void Release_Initialize(int64_t pid = 0);

  // Explicitly sets the process ID.
  void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);

  // Gets the associated process ID, in native form, and the creation timestamp
  // from memory without loading the entire structure for analysis. This will
  // return false if no valid process ID is available.
  static bool GetOwningProcessId(const void* memory,
                                 int64_t* out_id,
                                 int64_t* out_stamp);

  // SHA1(base::debug::OwningProcess): Increment this if structure changes!
  static constexpr uint32_t kPersistentTypeId = 0xB1179672 + 1;

  // Expected size for 32/64-bit check by PersistentMemoryAllocator.
  static constexpr size_t kExpectedInstanceSize = 24;

  std::atomic<uint32_t> data_id;
  uint32_t padding;
  int64_t process_id;
  int64_t create_stamp;
};

// The data associated with an activity is dependent upon the activity type.
// This union defines all of the various fields. All fields must be explicitly
// sized types to ensure no interoperability problems between 32-bit and
// 64-bit systems.
union ActivityData {
  // Expected size for 32/64-bit check.
  // TODO(bcwhite): VC2015 doesn't allow statics in unions. Fix when it does.
  // static constexpr size_t kExpectedInstanceSize = 8;

  // Generic activities don't have any defined structure.
  struct {
    uint32_t id;   // An arbitrary identifier used for association.
    int32_t info;  // An arbitrary value used for information purposes.
  } generic;
  struct {
    uint64_t sequence_id;  // The sequence identifier of the posted task.
  } task;
  struct {
    uint64_t lock_address;  // The memory address of the lock object.
  } lock;
  struct {
    uint64_t event_address;  // The memory address of the event object.
  } event;
  struct {
    int64_t thread_id;  // A unique identifier for a thread within a process.
  } thread;
  struct {
    int64_t process_id;  // A unique identifier for a process.
  } process;
  struct {
    uint32_t code;  // An "exception code" number.
  } exception;

  // These methods create an ActivityData object from the appropriate
  // parameters. Objects of this type should always be created this way to
  // ensure that no fields remain unpopulated should the set of recorded
  // fields change. They're defined inline where practical because they
  // reduce to loading a small local structure with a few values, roughly
  // the same as loading all those values into parameters.

  static ActivityData ForGeneric(uint32_t id, int32_t info) {
    ActivityData data;
    data.generic.id = id;
    data.generic.info = info;
    return data;
  }

  static ActivityData ForTask(uint64_t sequence) {
    ActivityData data;
    data.task.sequence_id = sequence;
    return data;
  }

  static ActivityData ForLock(const void* lock) {
    ActivityData data;
    data.lock.lock_address = reinterpret_cast<uintptr_t>(lock);
    return data;
  }

  static ActivityData ForEvent(const void* event) {
    ActivityData data;
    data.event.event_address = reinterpret_cast<uintptr_t>(event);
    return data;
  }

  static ActivityData ForThread(const PlatformThreadHandle& handle);
  static ActivityData ForThread(const int64_t id) {
    ActivityData data;
    data.thread.thread_id = id;
    return data;
  }

  static ActivityData ForProcess(const int64_t id) {
    ActivityData data;
    data.process.process_id = id;
    return data;
  }

  static ActivityData ForException(const uint32_t code) {
    ActivityData data;
    data.exception.code = code;
    return data;
  }
};

// A "null" activity-data that can be passed to indicate "do not change".
extern const ActivityData kNullActivityData;


// A helper class that is used for managing memory allocations within a
// persistent memory allocator. Instances of this class are NOT thread-safe.
// Use from a single thread or protect access with a lock.
class BASE_EXPORT ActivityTrackerMemoryAllocator {
 public:
  using Reference = PersistentMemoryAllocator::Reference;

  // Creates a instance for allocating objects of a fixed |object_type|, a
  // corresponding |object_free| type, and the |object_size|. An internal
  // cache of the last |cache_size| released references will be kept for
  // quick future fetches. If |make_iterable| then allocated objects will
  // be marked "iterable" in the allocator.
  ActivityTrackerMemoryAllocator(PersistentMemoryAllocator* allocator,
                                 uint32_t object_type,
                                 uint32_t object_free_type,
                                 size_t object_size,
                                 size_t cache_size,
                                 bool make_iterable);
  ~ActivityTrackerMemoryAllocator();

  // Gets a reference to an object of the configured type. This can return
  // a null reference if it was not possible to allocate the memory.
  Reference GetObjectReference();

  // Returns an object to the "free" pool.
  void ReleaseObjectReference(Reference ref);

  // Helper function to access an object allocated using this instance.
  template <typename T>
  T* GetAsObject(Reference ref) {
    return allocator_->GetAsObject<T>(ref);
  }

  // Similar to GetAsObject() but converts references to arrays of objects.
  template <typename T>
  T* GetAsArray(Reference ref, size_t count) {
    return allocator_->GetAsArray<T>(ref, object_type_, count);
  }

  // The current "used size" of the internal cache, visible for testing.
  size_t cache_used() const { return cache_used_; }

 private:
  PersistentMemoryAllocator* const allocator_;
  const uint32_t object_type_;
  const uint32_t object_free_type_;
  const size_t object_size_;
  const size_t cache_size_;
  const bool make_iterable_;

  // An iterator for going through persistent memory looking for free'd objects.
  PersistentMemoryAllocator::Iterator iterator_;

  // The cache of released object memories.
  std::unique_ptr<Reference[]> cache_values_;
  size_t cache_used_;

  DISALLOW_COPY_AND_ASSIGN(ActivityTrackerMemoryAllocator);
};


// This structure is the full contents recorded for every activity pushed
// onto the stack. The |activity_type| indicates what is actually stored in
// the |data| field. All fields must be explicitly sized types to ensure no
// interoperability problems between 32-bit and 64-bit systems.
struct Activity {
  // SHA1(base::debug::Activity): Increment this if structure changes!
  static constexpr uint32_t kPersistentTypeId = 0x99425159 + 1;
  // Expected size for 32/64-bit check. Update this if structure changes!
  static constexpr size_t kExpectedInstanceSize =
      48 + 8 * kActivityCallStackSize;

  // The type of an activity on the stack. Activities are broken into
  // categories with the category ID taking the top 4 bits and the lower
  // bits representing an action within that category. This combination
  // makes it easy to "switch" based on the type during analysis.
  enum Type : uint8_t {
    // This "null" constant is used to indicate "do not change" in calls.
    ACT_NULL = 0,

    // Task activities involve callbacks posted to a thread or thread-pool
    // using the PostTask() method or any of its friends.
    ACT_TASK = 1 << 4,
    ACT_TASK_RUN = ACT_TASK,

    // Lock activities involve the acquisition of "mutex" locks.
    ACT_LOCK = 2 << 4,
    ACT_LOCK_ACQUIRE = ACT_LOCK,
    ACT_LOCK_RELEASE,

    // Event activities involve operations on a WaitableEvent.
    ACT_EVENT = 3 << 4,
    ACT_EVENT_WAIT = ACT_EVENT,
    ACT_EVENT_SIGNAL,

    // Thread activities involve the life management of threads.
    ACT_THREAD = 4 << 4,
    ACT_THREAD_START = ACT_THREAD,
    ACT_THREAD_JOIN,

    // Process activities involve the life management of processes.
    ACT_PROCESS = 5 << 4,
    ACT_PROCESS_START = ACT_PROCESS,
    ACT_PROCESS_WAIT,

    // Exception activities indicate the occurence of something unexpected.
    ACT_EXCEPTION = 14 << 4,

    // Generic activities are user defined and can be anything.
    ACT_GENERIC = 15 << 4,

    // These constants can be used to separate the category and action from
    // a combined activity type.
    ACT_CATEGORY_MASK = 0xF << 4,
    ACT_ACTION_MASK = 0xF
  };

  // Internal representation of time. During collection, this is in "ticks"
  // but when returned in a snapshot, it is "wall time".
  int64_t time_internal;

  // The address that pushed the activity onto the stack as a raw number.
  uint64_t calling_address;

  // The address that is the origin of the activity if it not obvious from
  // the call stack. This is useful for things like tasks that are posted
  // from a completely different thread though most activities will leave
  // it null.
  uint64_t origin_address;

  // Array of program-counters that make up the top of the call stack.
  // Despite the fixed size, this list is always null-terminated. Entries
  // after the terminator have no meaning and may or may not also be null.
  // The list will be completely empty if call-stack collection is not
  // enabled.
  uint64_t call_stack[kActivityCallStackSize];

  // Reference to arbitrary user data within the persistent memory segment
  // and a unique identifier for it.
  uint32_t user_data_ref;
  uint32_t user_data_id;

  // The (enumerated) type of the activity. This defines what fields of the
  // |data| record are valid.
  uint8_t activity_type;

  // Padding to ensure that the next member begins on a 64-bit boundary
  // even on 32-bit builds which ensures inter-operability between CPU
  // architectures. New fields can be taken from this space.
  uint8_t padding[7];

  // Information specific to the |activity_type|.
  ActivityData data;

  static void FillFrom(Activity* activity,
                       const void* program_counter,
                       const void* origin,
                       Type type,
                       const ActivityData& data);
};

// This class manages arbitrary user data that can be associated with activities
// done by a thread by supporting key/value pairs of any type. This can provide
// additional information during debugging. It is also used to store arbitrary
// global data. All updates must be done from the same thread though other
// threads can read it concurrently if they create new objects using the same
// memory.
class BASE_EXPORT ActivityUserData {
 public:
  // List of known value type. REFERENCE types must immediately follow the non-
  // external types.
  enum ValueType : uint8_t {
    END_OF_VALUES = 0,
    RAW_VALUE,
    RAW_VALUE_REFERENCE,
    STRING_VALUE,
    STRING_VALUE_REFERENCE,
    CHAR_VALUE,
    BOOL_VALUE,
    SIGNED_VALUE,
    UNSIGNED_VALUE,
  };

  class BASE_EXPORT TypedValue {
   public:
    TypedValue();
    TypedValue(const TypedValue& other);
    ~TypedValue();

    ValueType type() const { return type_; }

    // These methods return the extracted value in the correct format.
    StringPiece Get() const;
    StringPiece GetString() const;
    bool GetBool() const;
    char GetChar() const;
    int64_t GetInt() const;
    uint64_t GetUint() const;

    // These methods return references to process memory as originally provided
    // to corresponding Set calls. USE WITH CAUTION! There is no guarantee that
    // the referenced memory is assessible or useful.  It's possible that:
    //  - the memory was free'd and reallocated for a different purpose
    //  - the memory has been released back to the OS
    //  - the memory belongs to a different process's address space
    // Dereferencing the returned StringPiece when the memory is not accessible
    // will cause the program to SEGV!
    StringPiece GetReference() const;
    StringPiece GetStringReference() const;

   private:
    friend class ActivityUserData;

    ValueType type_ = END_OF_VALUES;
    uint64_t short_value_;    // Used to hold copy of numbers, etc.
    std::string long_value_;  // Used to hold copy of raw/string data.
    StringPiece ref_value_;   // Used to hold reference to external data.
  };

  using Snapshot = std::map<std::string, TypedValue>;

  // Initialize the object either as a "sink" that just accepts and discards
  // data or an active one that writes to a given (zeroed) memory block.
  ActivityUserData();
  ActivityUserData(void* memory, size_t size, int64_t pid = 0);
  virtual ~ActivityUserData();

  // Gets the unique ID number for this user data. If this changes then the
  // contents have been overwritten by another thread. The return value is
  // always non-zero unless it's actually just a data "sink".
  uint32_t id() const {
    return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0;
  }

  // Writes a |value| (as part of a key/value pair) that will be included with
  // the activity in any reports. The same |name| can be written multiple times
  // with each successive call overwriting the previously stored |value|. For
  // raw and string values, the maximum size of successive writes is limited by
  // the first call. The length of "name" is limited to 255 characters.
  //
  // This information is stored on a "best effort" basis. It may be dropped if
  // the memory buffer is full or the associated activity is beyond the maximum
  // recording depth.
  void Set(StringPiece name, const void* memory, size_t size) {
    Set(name, RAW_VALUE, memory, size);
  }
  void SetString(StringPiece name, StringPiece value) {
    Set(name, STRING_VALUE, value.data(), value.length());
  }
  void SetString(StringPiece name, StringPiece16 value) {
    SetString(name, UTF16ToUTF8(value));
  }
  void SetBool(StringPiece name, bool value) {
    char cvalue = value ? 1 : 0;
    Set(name, BOOL_VALUE, &cvalue, sizeof(cvalue));
  }
  void SetChar(StringPiece name, char value) {
    Set(name, CHAR_VALUE, &value, sizeof(value));
  }
  void SetInt(StringPiece name, int64_t value) {
    Set(name, SIGNED_VALUE, &value, sizeof(value));
  }
  void SetUint(StringPiece name, uint64_t value) {
    Set(name, UNSIGNED_VALUE, &value, sizeof(value));
  }

  // These function as above but don't actually copy the data into the
  // persistent memory. They store unaltered pointers along with a size. These
  // can be used in conjuction with a memory dump to find certain large pieces
  // of information.
  void SetReference(StringPiece name, const void* memory, size_t size) {
    SetReference(name, RAW_VALUE_REFERENCE, memory, size);
  }
  void SetStringReference(StringPiece name, StringPiece value) {
    SetReference(name, STRING_VALUE_REFERENCE, value.data(), value.length());
  }

  // Creates a snapshot of the key/value pairs contained within. The returned
  // data will be fixed, independent of whatever changes afterward. There is
  // some protection against concurrent modification. This will return false
  // if the data is invalid or if a complete overwrite of the contents is
  // detected.
  bool CreateSnapshot(Snapshot* output_snapshot) const;

  // Gets the base memory address used for storing data.
  const void* GetBaseAddress() const;

  // Explicitly sets the process ID.
  void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);

  // Gets the associated process ID, in native form, and the creation timestamp
  // from tracker memory without loading the entire structure for analysis. This
  // will return false if no valid process ID is available.
  static bool GetOwningProcessId(const void* memory,
                                 int64_t* out_id,
                                 int64_t* out_stamp);

 protected:
  virtual void Set(StringPiece name,
                   ValueType type,
                   const void* memory,
                   size_t size);

 private:
  FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest);

  enum : size_t { kMemoryAlignment = sizeof(uint64_t) };

  // A structure that defines the structure header in memory.
  struct MemoryHeader {
    MemoryHeader();
    ~MemoryHeader();

    OwningProcess owner;  // Information about the creating process.
  };

  // Header to a key/value record held in persistent memory.
  struct FieldHeader {
    FieldHeader();
    ~FieldHeader();

    std::atomic<uint8_t> type;         // Encoded ValueType
    uint8_t name_size;                 // Length of "name" key.
    std::atomic<uint16_t> value_size;  // Actual size of of the stored value.
    uint16_t record_size;              // Total storage of name, value, header.
  };

  // A structure used to reference data held outside of persistent memory.
  struct ReferenceRecord {
    uint64_t address;
    uint64_t size;
  };

  // This record is used to hold known value is a map so that they can be
  // found and overwritten later.
  struct ValueInfo {
    ValueInfo();
    ValueInfo(ValueInfo&&);
    ~ValueInfo();

    StringPiece name;                 // The "key" of the record.
    ValueType type;                   // The type of the value.
    void* memory;                     // Where the "value" is held.
    std::atomic<uint16_t>* size_ptr;  // Address of the actual size of value.
    size_t extent;                    // The total storage of the value,
  };                                  // typically rounded up for alignment.

  void SetReference(StringPiece name,
                    ValueType type,
                    const void* memory,
                    size_t size);

  // Loads any data already in the memory segment. This allows for accessing
  // records created previously. If this detects that the underlying data has
  // gone away (cleared by another thread/process), it will invalidate all the
  // data in this object and turn it into simple "sink" with no values to
  // return.
  void ImportExistingData() const;

  // A map of all the values within the memory block, keyed by name for quick
  // updates of the values. This is "mutable" because it changes on "const"
  // objects even when the actual data values can't change.
  mutable std::map<StringPiece, ValueInfo> values_;

  // Information about the memory block in which new data can be stored. These
  // are "mutable" because they change even on "const" objects that are just
  // skipping already set values.
  mutable char* memory_;
  mutable size_t available_;

  // A pointer to the memory header for this instance.
  MemoryHeader* const header_;

  // These hold values used when initially creating the object. They are
  // compared against current header values to check for outside changes.
  const uint32_t orig_data_id;
  const int64_t orig_process_id;
  const int64_t orig_create_stamp;

  DISALLOW_COPY_AND_ASSIGN(ActivityUserData);
};

// This class manages tracking a stack of activities for a single thread in
// a persistent manner, implementing a bounded-size stack in a fixed-size
// memory allocation. In order to support an operational mode where another
// thread is analyzing this data in real-time, atomic operations are used
// where necessary to guarantee a consistent view from the outside.
//
// This class is not generally used directly but instead managed by the
// GlobalActivityTracker instance and updated using Scoped*Activity local
// objects.
class BASE_EXPORT ThreadActivityTracker {
 public:
  using ActivityId = uint32_t;

  // This structure contains all the common information about the thread so
  // it doesn't have to be repeated in every entry on the stack. It is defined
  // and used completely within the .cc file.
  struct Header;

  // This structure holds a copy of all the internal data at the moment the
  // "snapshot" operation is done. It is disconnected from the live tracker
  // so that continued operation of the thread will not cause changes here.
  struct BASE_EXPORT Snapshot {
    // Explicit constructor/destructor are needed because of complex types
    // with non-trivial default constructors and destructors.
    Snapshot();
    ~Snapshot();

    // The name of the thread as set when it was created. The name may be
    // truncated due to internal length limitations.
    std::string thread_name;

    // The timestamp at which this process was created.
    int64_t create_stamp;

    // The process and thread IDs. These values have no meaning other than
    // they uniquely identify a running process and a running thread within
    // that process.  Thread-IDs can be re-used across different processes
    // and both can be re-used after the process/thread exits.
    int64_t process_id = 0;
    int64_t thread_id = 0;

    // The current stack of activities that are underway for this thread. It
    // is limited in its maximum size with later entries being left off.
    std::vector<Activity> activity_stack;

    // The current total depth of the activity stack, including those later
    // entries not recorded in the |activity_stack| vector.
    uint32_t activity_stack_depth = 0;

    // The last recorded "exception" activity.
    Activity last_exception;
  };

  // This is the base class for having the compiler manage an activity on the
  // tracker's stack. It does nothing but call methods on the passed |tracker|
  // if it is not null, making it safe (and cheap) to create these objects
  // even if activity tracking is not enabled.
  class BASE_EXPORT ScopedActivity {
   public:
    ScopedActivity(ThreadActivityTracker* tracker,
                   const void* program_counter,
                   const void* origin,
                   Activity::Type type,
                   const ActivityData& data);
    ~ScopedActivity();

    // Changes some basic metadata about the activity.
    void ChangeTypeAndData(Activity::Type type, const ActivityData& data);

   protected:
    // The thread tracker to which this object reports. It can be null if
    // activity tracking is not (yet) enabled.
    ThreadActivityTracker* const tracker_;

    // An identifier that indicates a specific activity on the stack.
    ActivityId activity_id_;

   private:
    DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
  };

  // A ThreadActivityTracker runs on top of memory that is managed externally.
  // It must be large enough for the internal header and a few Activity
  // blocks. See SizeForStackDepth().
  ThreadActivityTracker(void* base, size_t size);
  virtual ~ThreadActivityTracker();

  // Indicates that an activity has started from a given |origin| address in
  // the code, though it can be null if the creator's address is not known.
  // The |type| and |data| describe the activity. |program_counter| should be
  // the result of GetProgramCounter() where push is called. Returned is an
  // ID that can be used to adjust the pushed activity.
  ActivityId PushActivity(const void* program_counter,
                          const void* origin,
                          Activity::Type type,
                          const ActivityData& data);

  // An inlined version of the above that gets the program counter where it
  // is called.
  ALWAYS_INLINE
  ActivityId PushActivity(const void* origin,
                          Activity::Type type,
                          const ActivityData& data) {
    return PushActivity(GetProgramCounter(), origin, type, data);
  }

  // Changes the activity |type| and |data| of the top-most entry on the stack.
  // This is useful if the information has changed and it is desireable to
  // track that change without creating a new stack entry. If the type is
  // ACT_NULL or the data is kNullActivityData then that value will remain
  // unchanged. The type, if changed, must remain in the same category.
  // Changing both is not atomic so a snapshot operation could occur between
  // the update of |type| and |data| or between update of |data| fields.
  void ChangeActivity(ActivityId id,
                      Activity::Type type,
                      const ActivityData& data);

  // Indicates that an activity has completed.
  void PopActivity(ActivityId id);

  // Sets the user-data information for an activity.
  std::unique_ptr<ActivityUserData> GetUserData(
      ActivityId id,
      ActivityTrackerMemoryAllocator* allocator);

  // Returns if there is true use-data associated with a given ActivityId since
  // it's possible than any returned object is just a sink.
  bool HasUserData(ActivityId id);

  // Release the user-data information for an activity.
  void ReleaseUserData(ActivityId id,
                       ActivityTrackerMemoryAllocator* allocator);

  // Save an exception. |origin| is the location of the exception.
  void RecordExceptionActivity(const void* program_counter,
                               const void* origin,
                               Activity::Type type,
                               const ActivityData& data);

  // Returns whether the current data is valid or not. It is not valid if
  // corruption has been detected in the header or other data structures.
  bool IsValid() const;

  // Gets a copy of the tracker contents for analysis. Returns false if a
  // snapshot was not possible, perhaps because the data is not valid; the
  // contents of |output_snapshot| are undefined in that case. The current
  // implementation does not support concurrent snapshot operations.
  bool CreateSnapshot(Snapshot* output_snapshot) const;

  // Gets the base memory address used for storing data.
  const void* GetBaseAddress();

  // Access the "data version" value so tests can determine if an activity
  // was pushed and popped in a single call.
  uint32_t GetDataVersionForTesting();

  // Explicitly sets the process ID.
  void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);

  // Gets the associated process ID, in native form, and the creation timestamp
  // from tracker memory without loading the entire structure for analysis. This
  // will return false if no valid process ID is available.
  static bool GetOwningProcessId(const void* memory,
                                 int64_t* out_id,
                                 int64_t* out_stamp);

  // Calculates the memory size required for a given stack depth, including
  // the internal header structure for the stack.
  static size_t SizeForStackDepth(int stack_depth);

 private:
  friend class ActivityTrackerTest;

  bool CalledOnValidThread();

  std::unique_ptr<ActivityUserData> CreateUserDataForActivity(
      Activity* activity,
      ActivityTrackerMemoryAllocator* allocator);

  Header* const header_;        // Pointer to the Header structure.
  Activity* const stack_;       // The stack of activities.

#if DCHECK_IS_ON()
  // The ActivityTracker is thread bound, and will be invoked across all the
  // sequences that run on the thread. A ThreadChecker does not work here, as it
  // asserts on running in the same sequence each time.
  const PlatformThreadRef thread_id_;  // The thread this instance is bound to.
#endif
  const uint32_t stack_slots_;  // The total number of stack slots.

  bool valid_ = false;          // Tracks whether the data is valid or not.

  DISALLOW_COPY_AND_ASSIGN(ThreadActivityTracker);
};


// The global tracker manages all the individual thread trackers. Memory for
// the thread trackers is taken from a PersistentMemoryAllocator which allows
// for the data to be analyzed by a parallel process or even post-mortem.
class BASE_EXPORT GlobalActivityTracker {
 public:
  // Type identifiers used when storing in persistent memory so they can be
  // identified during extraction; the first 4 bytes of the SHA1 of the name
  // is used as a unique integer. A "version number" is added to the base
  // so that, if the structure of that object changes, stored older versions
  // will be safely ignored. These are public so that an external process
  // can recognize records of this type within an allocator.
  enum : uint32_t {
    kTypeIdActivityTracker = 0x5D7381AF + 4,   // SHA1(ActivityTracker) v4
    kTypeIdUserDataRecord = 0x615EDDD7 + 3,    // SHA1(UserDataRecord) v3
    kTypeIdGlobalLogMessage = 0x4CF434F9 + 1,  // SHA1(GlobalLogMessage) v1
    kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100,

    kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker,
    kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
    kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord,
  };

  // An enumeration of common process life stages. All entries are given an
  // explicit number so they are known and remain constant; this allows for
  // cross-version analysis either locally or on a server.
  enum ProcessPhase : int {
    // The phases are generic and may have meaning to the tracker.
    PROCESS_PHASE_UNKNOWN = 0,
    PROCESS_LAUNCHED = 1,
    PROCESS_LAUNCH_FAILED = 2,
    PROCESS_EXITED_CLEANLY = 10,
    PROCESS_EXITED_WITH_CODE = 11,

    // Add here whatever is useful for analysis.
    PROCESS_SHUTDOWN_STARTED = 100,
    PROCESS_MAIN_LOOP_STARTED = 101,
  };

  // A callback made when a process exits to allow immediate analysis of its
  // data. Note that the system may reuse the |process_id| so when fetching
  // records it's important to ensure that what is returned was created before
  // the |exit_stamp|. Movement of |process_data| information is allowed.
  using ProcessExitCallback =
      Callback<void(int64_t process_id,
                    int64_t exit_stamp,
                    int exit_code,
                    ProcessPhase exit_phase,
                    std::string&& command_line,
                    ActivityUserData::Snapshot&& process_data)>;

  // This structure contains information about a loaded module, as shown to
  // users of the tracker.
  struct BASE_EXPORT ModuleInfo {
    ModuleInfo();
    ModuleInfo(ModuleInfo&& rhs);
    ModuleInfo(const ModuleInfo& rhs);
    ~ModuleInfo();

    ModuleInfo& operator=(ModuleInfo&& rhs);
    ModuleInfo& operator=(const ModuleInfo& rhs);

    // Information about where and when the module was loaded/unloaded.
    bool is_loaded = false;  // Was the last operation a load or unload?
    uintptr_t address = 0;   // Address of the last load operation.
    int64_t load_time = 0;   // Time of last change; set automatically.

    // Information about the module itself. These never change no matter how
    // many times a module may be loaded and unloaded.
    size_t size = 0;         // The size of the loaded module.
    uint32_t timestamp = 0;  // Opaque "timestamp" for the module.
    uint32_t age = 0;        // Opaque "age" for the module.
    uint8_t identifier[16];  // Opaque identifier (GUID, etc.) for the module.
    std::string file;        // The full path to the file. (UTF-8)
    std::string debug_file;  // The full path to the debug file.
  };

  // This is a thin wrapper around the thread-tracker's ScopedActivity that
  // allows thread-safe access to data values. It is safe to use even if
  // activity tracking is not enabled.
  class BASE_EXPORT ScopedThreadActivity
      : public ThreadActivityTracker::ScopedActivity {
   public:
    ScopedThreadActivity(const void* program_counter,
                         const void* origin,
                         Activity::Type type,
                         const ActivityData& data,
                         bool lock_allowed);
    ~ScopedThreadActivity();

    // Returns an object for manipulating user data.
    ActivityUserData& user_data();

   private:
    // Gets (or creates) a tracker for the current thread. If locking is not
    // allowed (because a lock is being tracked which would cause recursion)
    // then the attempt to create one if none found will be skipped. Once
    // the tracker for this thread has been created for other reasons, locks
    // will be tracked. The thread-tracker uses locks.
    static ThreadActivityTracker* GetOrCreateTracker(bool lock_allowed) {
      GlobalActivityTracker* global_tracker = Get();
      if (!global_tracker)
        return nullptr;

      if (lock_allowed)
        return global_tracker->GetOrCreateTrackerForCurrentThread();
      else
        return global_tracker->GetTrackerForCurrentThread();
    }

    // An object that manages additional user data, created only upon request.
    std::unique_ptr<ActivityUserData> user_data_;

    DISALLOW_COPY_AND_ASSIGN(ScopedThreadActivity);
  };

  ~GlobalActivityTracker();

  // Creates a global tracker using a given persistent-memory |allocator| and
  // providing the given |stack_depth| to each thread tracker it manages. The
  // created object is activated so tracking will begin immediately upon return.
  // The |process_id| can be zero to get it from the OS but is taken for testing
  // purposes.
  static void CreateWithAllocator(
      std::unique_ptr<PersistentMemoryAllocator> allocator,
      int stack_depth,
      int64_t process_id);

#if !defined(OS_NACL)
  // Like above but internally creates an allocator around a disk file with
  // the specified |size| at the given |file_path|. Any existing file will be
  // overwritten. The |id| and |name| are arbitrary and stored in the allocator
  // for reference by whatever process reads it. Returns true if successful.
  static bool CreateWithFile(const FilePath& file_path,
                             size_t size,
                             uint64_t id,
                             StringPiece name,
                             int stack_depth);
#endif  // !defined(OS_NACL)

  // Like above but internally creates an allocator using local heap memory of
  // the specified size. This is used primarily for unit tests. The |process_id|
  // can be zero to get it from the OS but is taken for testing purposes.
  static bool CreateWithLocalMemory(size_t size,
                                    uint64_t id,
                                    StringPiece name,
                                    int stack_depth,
                                    int64_t process_id);

#if !defined(STARBOARD)
  // Like above but internally creates an allocator using a shared-memory
  // segment. The segment must already be mapped into the local memory space.
  static bool CreateWithSharedMemory(std::unique_ptr<SharedMemory> shm,
                                     uint64_t id,
                                     StringPiece name,
                                     int stack_depth);

  // Like above but takes a handle to an existing shared memory segment and
  // maps it before creating the tracker.
  static bool CreateWithSharedMemoryHandle(const SharedMemoryHandle& handle,
                                           size_t size,
                                           uint64_t id,
                                           StringPiece name,
                                           int stack_depth);
#endif  // !defined(STARBOARD)

  // Gets the global activity-tracker or null if none exists.
  static GlobalActivityTracker* Get() {
    return reinterpret_cast<GlobalActivityTracker*>(
        subtle::Acquire_Load(&g_tracker_));
  }

  // Sets the global activity-tracker for testing purposes.
  static void SetForTesting(std::unique_ptr<GlobalActivityTracker> tracker);

  // This access to the persistent allocator is only for testing; it extracts
  // the global tracker completely. All tracked threads must exit before
  // calling this. Tracking for the current thread will be automatically
  // stopped.
  static std::unique_ptr<GlobalActivityTracker> ReleaseForTesting();

  // Convenience method for determining if a global tracker is active.
  static bool IsEnabled() { return Get() != nullptr; }

  // Gets the persistent-memory-allocator in which data is stored. Callers
  // can store additional records here to pass more information to the
  // analysis process.
  PersistentMemoryAllocator* allocator() { return allocator_.get(); }

  // Gets the thread's activity-tracker if it exists. This is inline for
  // performance reasons and it uses thread-local-storage (TLS) so that there
  // is no significant lookup time required to find the one for the calling
  // thread. Ownership remains with the global tracker.
  ThreadActivityTracker* GetTrackerForCurrentThread() {
    // It is not safe to use TLS once TLS has been destroyed.
    if (base::ThreadLocalStorage::HasBeenDestroyed())
      return nullptr;

    return reinterpret_cast<ThreadActivityTracker*>(this_thread_tracker_.Get());
  }

  // Gets the thread's activity-tracker or creates one if none exists. This
  // is inline for performance reasons. Ownership remains with the global
  // tracker.
  ThreadActivityTracker* GetOrCreateTrackerForCurrentThread() {
    ThreadActivityTracker* tracker = GetTrackerForCurrentThread();
    if (tracker)
      return tracker;
    return CreateTrackerForCurrentThread();
  }

  // Creates an activity-tracker for the current thread.
  ThreadActivityTracker* CreateTrackerForCurrentThread();

  // Releases the activity-tracker for the current thread (for testing only).
  void ReleaseTrackerForCurrentThreadForTesting();

  // Sets a task-runner that can be used for background work.
  void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner);

  // Sets an optional callback to be called when a process exits.
  void SetProcessExitCallback(ProcessExitCallback callback);

  // Manages process lifetimes. These are called by the process that launched
  // and reaped the subprocess, not the subprocess itself. If it is expensive
  // to generate the parameters, Get() the global tracker and call these
  // conditionally rather than using the static versions.
  void RecordProcessLaunch(ProcessId process_id,
                           const FilePath::StringType& cmd);
  void RecordProcessLaunch(ProcessId process_id,
                           const FilePath::StringType& exe,
                           const FilePath::StringType& args);
  void RecordProcessExit(ProcessId process_id, int exit_code);
  static void RecordProcessLaunchIfEnabled(ProcessId process_id,
                                           const FilePath::StringType& cmd) {
    GlobalActivityTracker* tracker = Get();
    if (tracker)
      tracker->RecordProcessLaunch(process_id, cmd);
  }
  static void RecordProcessLaunchIfEnabled(ProcessId process_id,
                                           const FilePath::StringType& exe,
                                           const FilePath::StringType& args) {
    GlobalActivityTracker* tracker = Get();
    if (tracker)
      tracker->RecordProcessLaunch(process_id, exe, args);
  }
  static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) {
    GlobalActivityTracker* tracker = Get();
    if (tracker)
      tracker->RecordProcessExit(process_id, exit_code);
  }

  // Sets the "phase" of the current process, useful for knowing what it was
  // doing when it last reported.
  void SetProcessPhase(ProcessPhase phase);
  static void SetProcessPhaseIfEnabled(ProcessPhase phase) {
    GlobalActivityTracker* tracker = Get();
    if (tracker)
      tracker->SetProcessPhase(phase);
  }

  // Records a log message. The current implementation does NOT recycle these
  // only store critical messages such as FATAL ones.
  void RecordLogMessage(StringPiece message);
  static void RecordLogMessageIfEnabled(StringPiece message) {
    GlobalActivityTracker* tracker = Get();
    if (tracker)
      tracker->RecordLogMessage(message);
  }

  // Records a module load/unload event. This is safe to call multiple times
  // even with the same information.
  void RecordModuleInfo(const ModuleInfo& info);
  static void RecordModuleInfoIfEnabled(const ModuleInfo& info) {
    GlobalActivityTracker* tracker = Get();
    if (tracker)
      tracker->RecordModuleInfo(info);
  }

  // Record field trial information. This call is thread-safe. In addition to
  // this, construction of a GlobalActivityTracker will cause all existing
  // active field trials to be fetched and recorded.
  void RecordFieldTrial(const std::string& trial_name, StringPiece group_name);
  static void RecordFieldTrialIfEnabled(const std::string& trial_name,
                                        StringPiece group_name) {
    GlobalActivityTracker* tracker = Get();
    if (tracker)
      tracker->RecordFieldTrial(trial_name, group_name);
  }

  // Record exception information for the current thread.
  ALWAYS_INLINE
  void RecordException(const void* origin, uint32_t code) {
    return RecordExceptionImpl(GetProgramCounter(), origin, code);
  }
  void RecordException(const void* pc, const void* origin, uint32_t code);

  // Marks the tracked data as deleted.
  void MarkDeleted();

  // Gets the process ID used for tracking. This is typically the same as what
  // the OS thinks is the current process but can be overridden for testing.
  int64_t process_id() { return process_id_; }

  // Accesses the process data record for storing arbitrary key/value pairs.
  // Updates to this are thread-safe.
  ActivityUserData& process_data() { return process_data_; }

 private:
  friend class GlobalActivityAnalyzer;
  friend class ScopedThreadActivity;
  friend class ActivityTrackerTest;

  enum : int {
    // The maximum number of threads that can be tracked within a process. If
    // more than this number run concurrently, tracking of new ones may cease.
    kMaxThreadCount = 100,
    kCachedThreadMemories = 10,
    kCachedUserDataMemories = 10,
  };

  // A wrapper around ActivityUserData that is thread-safe and thus can be used
  // in the global scope without the requirement of being called from only one
  // thread.
  class ThreadSafeUserData : public ActivityUserData {
   public:
    ThreadSafeUserData(void* memory, size_t size, int64_t pid = 0);
    ~ThreadSafeUserData() override;

   private:
    void Set(StringPiece name,
             ValueType type,
             const void* memory,
             size_t size) override;

    Lock data_lock_;

    DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData);
  };

  // State of a module as stored in persistent memory. This supports a single
  // loading of a module only. If modules are loaded multiple times at
  // different addresses, only the last will be recorded and an unload will
  // not revert to the information of any other addresses.
  struct BASE_EXPORT ModuleInfoRecord {
    // SHA1(ModuleInfoRecord): Increment this if structure changes!
    static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;

    // Expected size for 32/64-bit check by PersistentMemoryAllocator.
    static constexpr size_t kExpectedInstanceSize =
        OwningProcess::kExpectedInstanceSize + 56;

    // The atomic unfortunately makes this a "complex" class on some compilers
    // and thus requires an out-of-line constructor & destructor even though
    // they do nothing.
    ModuleInfoRecord();
    ~ModuleInfoRecord();

    OwningProcess owner;            // The process that created this record.
    uint64_t address;               // The base address of the module.
    uint64_t load_time;             // Time of last load/unload.
    uint64_t size;                  // The size of the module in bytes.
    uint32_t timestamp;             // Opaque timestamp of the module.
    uint32_t age;                   // Opaque "age" associated with the module.
    uint8_t identifier[16];         // Opaque identifier for the module.
    std::atomic<uint32_t> changes;  // Number load/unload actions.
    uint16_t pickle_size;           // The size of the following pickle.
    uint8_t loaded;                 // Flag if module is loaded or not.
    char pickle[1];                 // Other strings; may allocate larger.

    // Decodes/encodes storage structure from more generic info structure.
    bool DecodeTo(GlobalActivityTracker::ModuleInfo* info,
                  size_t record_size) const;
    static ModuleInfoRecord* CreateFrom(
        const GlobalActivityTracker::ModuleInfo& info,
        PersistentMemoryAllocator* allocator);

    // Updates the core information without changing the encoded strings. This
    // is useful when a known module changes state (i.e. new load or unload).
    bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info);

   private:
    DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord);
  };

  // A thin wrapper around the main thread-tracker that keeps additional
  // information that the global tracker needs to handle joined threads.
  class ManagedActivityTracker : public ThreadActivityTracker {
   public:
    ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference,
                           void* base,
                           size_t size);
    ~ManagedActivityTracker() override;

    // The reference into persistent memory from which the thread-tracker's
    // memory was created.
    const PersistentMemoryAllocator::Reference mem_reference_;

    // The physical address used for the thread-tracker's memory.
    void* const mem_base_;

   private:
    DISALLOW_COPY_AND_ASSIGN(ManagedActivityTracker);
  };

  // Creates a global tracker using a given persistent-memory |allocator| and
  // providing the given |stack_depth| to each thread tracker it manages. The
  // created object is activated so tracking has already started upon return.
  // The |process_id| can be zero to get it from the OS but is taken for testing
  // purposes.
  GlobalActivityTracker(std::unique_ptr<PersistentMemoryAllocator> allocator,
                        int stack_depth,
                        int64_t process_id);

  // Returns the memory used by an activity-tracker managed by this class.
  // It is called during the destruction of a ManagedActivityTracker object.
  void ReturnTrackerMemory(ManagedActivityTracker* tracker);

  // Records exception information.
  void RecordExceptionImpl(const void* pc, const void* origin, uint32_t code);

  // Releases the activity-tracker associcated with thread. It is called
  // automatically when a thread is joined and thus there is nothing more to
  // be tracked. |value| is a pointer to a ManagedActivityTracker.
  static void OnTLSDestroy(void* value);

  // Does process-exit work. This can be run on any thread.
  void CleanupAfterProcess(int64_t process_id,
                           int64_t exit_stamp,
                           int exit_code,
                           std::string&& command_line);

  // The persistent-memory allocator from which the memory for all trackers
  // is taken.
  std::unique_ptr<PersistentMemoryAllocator> allocator_;

  // The size (in bytes) of memory required by a ThreadActivityTracker to
  // provide the stack-depth requested during construction.
  const size_t stack_memory_size_;

  // The process-id of the current process. This is kept as a member variable,
  // defined during initialization, for testing purposes.
  const int64_t process_id_;

  // The activity tracker for the currently executing thread.
  ThreadLocalStorage::Slot this_thread_tracker_;

  // The number of thread trackers currently active.
  std::atomic<int> thread_tracker_count_;

  // A caching memory allocator for thread-tracker objects.
  ActivityTrackerMemoryAllocator thread_tracker_allocator_;
  Lock thread_tracker_allocator_lock_;

  // A caching memory allocator for user data attached to activity data.
  ActivityTrackerMemoryAllocator user_data_allocator_;
  Lock user_data_allocator_lock_;

  // An object for holding arbitrary key value pairs with thread-safe access.
  ThreadSafeUserData process_data_;

  // A map of global module information, keyed by module path.
  std::map<const std::string, ModuleInfoRecord*> modules_;
  Lock modules_lock_;

  // The active global activity tracker.
  static subtle::AtomicWord g_tracker_;

  // A lock that is used to protect access to the following fields.
  Lock global_tracker_lock_;

  // The collection of processes being tracked and their command-lines.
  std::map<int64_t, std::string> known_processes_;

  // A task-runner that can be used for doing background processing.
  scoped_refptr<TaskRunner> background_task_runner_;

  // A callback performed when a subprocess exits, including its exit-code
  // and the phase it was in when that occurred. This will be called via
  // the |background_task_runner_| if one is set or whatever thread reaped
  // the process otherwise.
  ProcessExitCallback process_exit_callback_;

  DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
};


// Record entry in to and out of an arbitrary block of code.
class BASE_EXPORT ScopedActivity
    : public GlobalActivityTracker::ScopedThreadActivity {
 public:
  // Track activity at the specified FROM_HERE location for an arbitrary
  // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary
  // |info|. None of these values affect operation; they're all purely
  // for association and analysis. To have unique identifiers across a
  // diverse code-base, create the number by taking the first 8 characters
  // of the hash of the activity being tracked.
  //
  // For example:
  //   Tracking method: void MayNeverExit(uint32_t foo) {...}
  //   echo -n "MayNeverExit" | sha1sum   =>   e44873ccab21e2b71270da24aa1...
  //
  //   void MayNeverExit(int32_t foo) {
  //     base::debug::ScopedActivity track_me(0, 0xE44873CC, foo);
  //     ...
  //   }
  ALWAYS_INLINE
  ScopedActivity(uint8_t action, uint32_t id, int32_t info)
      : ScopedActivity(GetProgramCounter(), action, id, info) {}
  ScopedActivity() : ScopedActivity(0, 0, 0) {}

  // Changes the |action| and/or |info| of this activity on the stack. This
  // is useful for tracking progress through a function, updating the action
  // to indicate "milestones" in the block (max 16 milestones: 0-15) or the
  // info to reflect other changes. Changing both is not atomic so a snapshot
  // operation could occur between the update of |action| and |info|.
  void ChangeAction(uint8_t action);
  void ChangeInfo(int32_t info);
  void ChangeActionAndInfo(uint8_t action, int32_t info);

 private:
  // Constructs the object using a passed-in program-counter.
  ScopedActivity(const void* program_counter,
                 uint8_t action,
                 uint32_t id,
                 int32_t info);

  // A copy of the ID code so it doesn't have to be passed by the caller when
  // changing the |info| field.
  uint32_t id_;

  DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
};


// These "scoped" classes provide easy tracking of various blocking actions.

class BASE_EXPORT ScopedTaskRunActivity
    : public GlobalActivityTracker::ScopedThreadActivity {
 public:
  ALWAYS_INLINE
  explicit ScopedTaskRunActivity(const PendingTask& task)
      : ScopedTaskRunActivity(GetProgramCounter(), task) {}

 private:
  ScopedTaskRunActivity(const void* program_counter, const PendingTask& task);
  DISALLOW_COPY_AND_ASSIGN(ScopedTaskRunActivity);
};

class BASE_EXPORT ScopedLockAcquireActivity
    : public GlobalActivityTracker::ScopedThreadActivity {
 public:
  ALWAYS_INLINE
  explicit ScopedLockAcquireActivity(const base::internal::LockImpl* lock)
      : ScopedLockAcquireActivity(GetProgramCounter(), lock) {}

 private:
  ScopedLockAcquireActivity(const void* program_counter,
                            const base::internal::LockImpl* lock);
  DISALLOW_COPY_AND_ASSIGN(ScopedLockAcquireActivity);
};

class BASE_EXPORT ScopedEventWaitActivity
    : public GlobalActivityTracker::ScopedThreadActivity {
 public:
  ALWAYS_INLINE
  explicit ScopedEventWaitActivity(const WaitableEvent* event)
      : ScopedEventWaitActivity(GetProgramCounter(), event) {}

 private:
  ScopedEventWaitActivity(const void* program_counter,
                          const WaitableEvent* event);
  DISALLOW_COPY_AND_ASSIGN(ScopedEventWaitActivity);
};

class BASE_EXPORT ScopedThreadJoinActivity
    : public GlobalActivityTracker::ScopedThreadActivity {
 public:
  ALWAYS_INLINE
  explicit ScopedThreadJoinActivity(const PlatformThreadHandle* thread)
      : ScopedThreadJoinActivity(GetProgramCounter(), thread) {}

 private:
  ScopedThreadJoinActivity(const void* program_counter,
                           const PlatformThreadHandle* thread);
  DISALLOW_COPY_AND_ASSIGN(ScopedThreadJoinActivity);
};

// Some systems don't have base::Process
#if !defined(OS_NACL) && !defined(OS_IOS)
class BASE_EXPORT ScopedProcessWaitActivity
    : public GlobalActivityTracker::ScopedThreadActivity {
 public:
  ALWAYS_INLINE
  explicit ScopedProcessWaitActivity(const Process* process)
      : ScopedProcessWaitActivity(GetProgramCounter(), process) {}

 private:
  ScopedProcessWaitActivity(const void* program_counter,
                            const Process* process);
  DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
};
#endif

}  // namespace debug
}  // namespace base

#endif  // BASE_DEBUG_ACTIVITY_TRACKER_H_
