tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PHC.h (5702B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef PHC_h
      8 #define PHC_h
      9 
     10 #include "mozilla/Maybe.h"
     11 #include <stdint.h>
     12 #include <stdlib.h>
     13 
     14 #include "mozmemory_wrap.h"
     15 
     16 namespace mozilla {
     17 namespace phc {
     18 
     19 // Note: a stack trace may have no frames due to a collection problem.
     20 //
     21 // Also note: a more compact stack trace representation could be achieved with
     22 // some effort.
     23 struct StackTrace {
     24 public:
     25  static const size_t kMaxFrames = 16;
     26 
     27  // The number of PCs in the stack trace.
     28  size_t mLength;
     29 
     30  // The PCs in the stack trace. Only the first mLength are initialized.
     31  const void* mPcs[kMaxFrames];
     32 
     33 public:
     34  StackTrace() : mLength(0) {}
     35 };
     36 
     37 // Info from PHC about an address in memory.
     38 class AddrInfo {
     39 public:
     40  enum class Kind {
     41    // The address is not in PHC-managed memory.
     42    Unknown = 0,
     43 
     44    // The address is within a PHC page that has never been allocated. A crash
     45    // involving such an address is unlikely in practice, because it would
     46    // require the crash to happen quite early.
     47    NeverAllocatedPage = 1,
     48 
     49    // The address is within a PHC page that is in use.
     50    InUsePage = 2,
     51 
     52    // The address is within a PHC page that has been allocated and then freed.
     53    // A crash involving such an address most likely indicates a
     54    // use-after-free. (A sufficiently wild write -- e.g. a large buffer
     55    // overflow -- could also trigger it, but this is less likely.)
     56    FreedPage = 3,
     57 
     58    // The address is within a PHC guard page. A crash involving such an
     59    // address most likely indicates a buffer overflow. (Again, a sufficiently
     60    // wild write could unluckily trigger it, but this is less likely.)
     61    GuardPage = 4,
     62  };
     63 
     64  // The page kind.
     65  Kind mKind;
     66 
     67  // The starting address of the allocation.
     68  // - Unknown | NeverAllocatedPage: nullptr.
     69  // - InUsePage | FreedPage: the address of the allocation within the page.
     70  // - GuardPage: the mBaseAddr value from the preceding allocation page.
     71  const void* mBaseAddr;
     72 
     73  // The usable size, which could be bigger than the requested size.
     74  // - Unknown | NeverAllocatePage: 0.
     75  // - InUsePage | FreedPage: the usable size of the allocation within the page.
     76  // - GuardPage: the mUsableSize value from the preceding allocation page.
     77  size_t mUsableSize;
     78 
     79  // The allocation stack.
     80  // - Unknown | NeverAllocatedPage: Nothing.
     81  // - InUsePage | FreedPage: Some.
     82  // - GuardPage: the mAllocStack value from the preceding allocation page.
     83  mozilla::Maybe<StackTrace> mAllocStack;
     84 
     85  // The free stack.
     86  // - Unknown | NeverAllocatedPage | InUsePage: Nothing.
     87  // - FreedPage: Some.
     88  // - GuardPage: the mFreeStack value from the preceding allocation page.
     89  mozilla::Maybe<StackTrace> mFreeStack;
     90 
     91  // True if PHC was locked and therefore we couldn't retrive some infomation.
     92  bool mPhcWasLocked = false;
     93 
     94  // Default to no PHC info.
     95  AddrInfo() : mKind(Kind::Unknown), mBaseAddr(nullptr), mUsableSize(0) {}
     96 };
     97 
     98 // Global instance that is retrieved by the process generating the crash report
     99 extern AddrInfo gAddrInfo;
    100 
    101 // If this is a PHC-handled address, return true, and if an AddrInfo is
    102 // provided, fill in all of its fields. Otherwise, return false and leave
    103 // AddrInfo unchanged.
    104 MOZ_JEMALLOC_API bool IsPHCAllocation(const void*, AddrInfo*);
    105 
    106 // Disable PHC allocations on the current thread. Only useful for tests. Note
    107 // that PHC deallocations will still occur as needed.
    108 MOZ_JEMALLOC_API void DisablePHCOnCurrentThread();
    109 
    110 // Re-enable PHC allocations on the current thread. Only useful for tests.
    111 MOZ_JEMALLOC_API void ReenablePHCOnCurrentThread();
    112 
    113 // Test whether PHC allocations are enabled on the current thread. Only
    114 // useful for tests.
    115 MOZ_JEMALLOC_API bool IsPHCEnabledOnCurrentThread();
    116 
    117 // PHC has three different states:
    118 //  * Not compiled in
    119 //  * OnlyFree         - The memory allocator is hooked but new allocations
    120 //                       requests will be forwarded to mozjemalloc, free() will
    121 //                       correctly free any PHC allocations and realloc() will
    122 //                       "move" PHC allocations to mozjemalloc allocations.
    123 //  * Enabled          - Full use.
    124 enum PHCState {
    125  OnlyFree,
    126  Enabled,
    127 };
    128 
    129 MOZ_JEMALLOC_API void SetPHCState(PHCState aState);
    130 
    131 // Set the maximum allowed memory usage of PHC, including fragmentation and
    132 // metadata.
    133 MOZ_JEMALLOC_API void SetPHCSize(size_t aNumPHCBytes);
    134 
    135 MOZ_JEMALLOC_API void SetPHCProbabilities(int64_t aAvgDelayFirst,
    136                                          int64_t aAvgDelayNormal,
    137                                          int64_t aAvgDelayPageReuse);
    138 
    139 struct MemoryUsage {
    140  // The amount of memory used for PHC metadata, eg information about each
    141  // allocation including stacks.
    142  size_t mMetadataBytes = 0;
    143 
    144  // The amount of memory lost due to rounding allocation sizes up to the
    145  // nearest page.  AKA internal fragmentation.
    146  size_t mFragmentationBytes = 0;
    147 
    148  // The amount of memory allocated from PHC.
    149  size_t mAllocatedBytes = 0;
    150 };
    151 
    152 MOZ_JEMALLOC_API void PHCMemoryUsage(MemoryUsage& aMemoryUsage);
    153 
    154 struct PHCStats {
    155  size_t mSlotsAllocated = 0;
    156  size_t mSlotsFreed = 0;
    157  size_t mSlotsUnused = 0;
    158 };
    159 
    160 // Return PHC memory usage information by filling in the supplied structure.
    161 MOZ_JEMALLOC_API void GetPHCStats(PHCStats& aStats);
    162 
    163 }  // namespace phc
    164 }  // namespace mozilla
    165 
    166 // Initialise PHC (called from mozjemalloc's initialisation.
    167 void phc_init();
    168 
    169 #endif /* PHC_h */