// 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;

      // It is not safe to use TLS once TLS has been destroyed. This can happen
      // if code that runs late during thread destruction tries to use a
      // base::Lock. See https://crbug.com/864589.
      if (base::ThreadLocalStorage::HasBeenDestroyed())
        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);

  // 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);

  // 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() {
    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_
