1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=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 LulMain_h 8 #define LulMain_h 9 10 #include "PlatformMacros.h" 11 #include "mozilla/Atomics.h" 12 #include "mozilla/MemoryReporting.h" 13 14 // LUL: A Lightweight Unwind Library. 15 // This file provides the end-user (external) interface for LUL. 16 17 // Some comments about naming in the implementation. These are safe 18 // to ignore if you are merely using LUL, but are important if you 19 // hack on its internals. 20 // 21 // Debuginfo readers in general have tended to use the word "address" 22 // to mean several different things. This sometimes makes them 23 // difficult to understand and maintain. LUL tries hard to avoid 24 // using the word "address" and instead uses the following more 25 // precise terms: 26 // 27 // * SVMA ("Stated Virtual Memory Address"): this is an address of a 28 // symbol (etc) as it is stated in the symbol table, or other 29 // metadata, of an object. Such values are typically small and 30 // start from zero or thereabouts, unless the object has been 31 // prelinked. 32 // 33 // * AVMA ("Actual Virtual Memory Address"): this is the address of a 34 // symbol (etc) in a running process, that is, once the associated 35 // object has been mapped into a process. Such values are typically 36 // much larger than SVMAs, since objects can get mapped arbitrarily 37 // far along the address space. 38 // 39 // * "Bias": the difference between AVMA and SVMA for a given symbol 40 // (specifically, AVMA - SVMA). The bias is always an integral 41 // number of pages. Once we know the bias for a given object's 42 // text section (for example), we can compute the AVMAs of all of 43 // its text symbols by adding the bias to their SVMAs. 44 // 45 // * "Image address": typically, to read debuginfo from an object we 46 // will temporarily mmap in the file so as to read symbol tables 47 // etc. Addresses in this temporary mapping are called "Image 48 // addresses". Note that the temporary mapping is entirely 49 // unrelated to the mappings of the file that the dynamic linker 50 // must perform merely in order to get the program to run. Hence 51 // image addresses are unrelated to either SVMAs or AVMAs. 52 53 namespace lul { 54 55 // A machine word plus validity tag. 56 class TaggedUWord { 57 public: 58 // RUNS IN NO-MALLOC CONTEXT 59 // Construct a valid one. TaggedUWord(uintptr_t w)60 explicit TaggedUWord(uintptr_t w) : mValue(w), mValid(true) {} 61 62 // RUNS IN NO-MALLOC CONTEXT 63 // Construct an invalid one. TaggedUWord()64 TaggedUWord() : mValue(0), mValid(false) {} 65 66 // RUNS IN NO-MALLOC CONTEXT 67 TaggedUWord operator+(TaggedUWord rhs) const { 68 return (Valid() && rhs.Valid()) ? TaggedUWord(Value() + rhs.Value()) 69 : TaggedUWord(); 70 } 71 72 // RUNS IN NO-MALLOC CONTEXT 73 TaggedUWord operator-(TaggedUWord rhs) const { 74 return (Valid() && rhs.Valid()) ? TaggedUWord(Value() - rhs.Value()) 75 : TaggedUWord(); 76 } 77 78 // RUNS IN NO-MALLOC CONTEXT 79 TaggedUWord operator&(TaggedUWord rhs) const { 80 return (Valid() && rhs.Valid()) ? TaggedUWord(Value() & rhs.Value()) 81 : TaggedUWord(); 82 } 83 84 // RUNS IN NO-MALLOC CONTEXT 85 TaggedUWord operator|(TaggedUWord rhs) const { 86 return (Valid() && rhs.Valid()) ? TaggedUWord(Value() | rhs.Value()) 87 : TaggedUWord(); 88 } 89 90 // RUNS IN NO-MALLOC CONTEXT CmpGEs(TaggedUWord rhs)91 TaggedUWord CmpGEs(TaggedUWord rhs) const { 92 if (Valid() && rhs.Valid()) { 93 intptr_t s1 = (intptr_t)Value(); 94 intptr_t s2 = (intptr_t)rhs.Value(); 95 return TaggedUWord(s1 >= s2 ? 1 : 0); 96 } 97 return TaggedUWord(); 98 } 99 100 // RUNS IN NO-MALLOC CONTEXT 101 TaggedUWord operator<<(TaggedUWord rhs) const { 102 if (Valid() && rhs.Valid()) { 103 uintptr_t shift = rhs.Value(); 104 if (shift < 8 * sizeof(uintptr_t)) return TaggedUWord(Value() << shift); 105 } 106 return TaggedUWord(); 107 } 108 109 // RUNS IN NO-MALLOC CONTEXT 110 // Is equal? Note: non-validity on either side gives non-equality. 111 bool operator==(TaggedUWord other) const { 112 return (mValid && other.Valid()) ? (mValue == other.Value()) : false; 113 } 114 115 // RUNS IN NO-MALLOC CONTEXT 116 // Is it word-aligned? IsAligned()117 bool IsAligned() const { 118 return mValid && (mValue & (sizeof(uintptr_t) - 1)) == 0; 119 } 120 121 // RUNS IN NO-MALLOC CONTEXT Value()122 uintptr_t Value() const { return mValue; } 123 124 // RUNS IN NO-MALLOC CONTEXT Valid()125 bool Valid() const { return mValid; } 126 127 private: 128 uintptr_t mValue; 129 bool mValid; 130 }; 131 132 // The registers, with validity tags, that will be unwound. 133 134 struct UnwindRegs { 135 #if defined(GP_ARCH_arm) 136 TaggedUWord r7; 137 TaggedUWord r11; 138 TaggedUWord r12; 139 TaggedUWord r13; 140 TaggedUWord r14; 141 TaggedUWord r15; 142 #elif defined(GP_ARCH_arm64) 143 TaggedUWord x29; 144 TaggedUWord x30; 145 TaggedUWord sp; 146 TaggedUWord pc; 147 #elif defined(GP_ARCH_amd64) || defined(GP_ARCH_x86) 148 TaggedUWord xbp; 149 TaggedUWord xsp; 150 TaggedUWord xip; 151 #elif defined(GP_ARCH_mips64) 152 TaggedUWord sp; 153 TaggedUWord fp; 154 TaggedUWord pc; 155 #else 156 # error "Unknown plat" 157 #endif 158 }; 159 160 // The maximum number of bytes in a stack snapshot. This value can be increased 161 // if necessary, but testing showed that 160k is enough to obtain good 162 // backtraces on x86_64 Linux. Most backtraces fit comfortably into 4-8k of 163 // stack space, but we do have some very deep stacks occasionally. Please see 164 // the comments in DoNativeBacktrace as to why it's OK to have this value be so 165 // large. 166 static const size_t N_STACK_BYTES = 160 * 1024; 167 168 // The stack chunk image that will be unwound. 169 struct StackImage { 170 // [start_avma, +len) specify the address range in the buffer. 171 // Obviously we require 0 <= len <= N_STACK_BYTES. 172 uintptr_t mStartAvma; 173 size_t mLen; 174 uint8_t mContents[N_STACK_BYTES]; 175 }; 176 177 // Statistics collection for the unwinder. 178 template <typename T> 179 class LULStats { 180 public: LULStats()181 LULStats() : mContext(0), mCFI(0), mFP(0) {} 182 183 template <typename S> LULStats(const LULStats<S> & aOther)184 explicit LULStats(const LULStats<S>& aOther) 185 : mContext(aOther.mContext), mCFI(aOther.mCFI), mFP(aOther.mFP) {} 186 187 template <typename S> 188 LULStats<T>& operator=(const LULStats<S>& aOther) { 189 mContext = aOther.mContext; 190 mCFI = aOther.mCFI; 191 mFP = aOther.mFP; 192 return *this; 193 } 194 195 template <typename S> 196 uint32_t operator-(const LULStats<S>& aOther) { 197 return (mContext - aOther.mContext) + (mCFI - aOther.mCFI) + 198 (mFP - aOther.mFP); 199 } 200 201 T mContext; // Number of context frames 202 T mCFI; // Number of CFI/EXIDX frames 203 T mFP; // Number of frame-pointer recovered frames 204 }; 205 206 // The core unwinder library class. Just one of these is needed, and 207 // it can be shared by multiple unwinder threads. 208 // 209 // The library operates in one of two modes. 210 // 211 // * Admin mode. The library is this state after creation. In Admin 212 // mode, no unwinding may be performed. It is however allowable to 213 // perform administrative tasks -- primarily, loading of unwind info 214 // -- in this mode. In particular, it is safe for the library to 215 // perform dynamic memory allocation in this mode. Safe in the 216 // sense that there is no risk of deadlock against unwinding threads 217 // that might -- because of where they have been sampled -- hold the 218 // system's malloc lock. 219 // 220 // * Unwind mode. In this mode, calls to ::Unwind may be made, but 221 // nothing else. ::Unwind guarantees not to make any dynamic memory 222 // requests, so as to guarantee that the calling thread won't 223 // deadlock in the case where it already holds the system's malloc lock. 224 // 225 // The library is created in Admin mode. After debuginfo is loaded, 226 // the caller must switch it into Unwind mode by calling 227 // ::EnableUnwinding. There is no way to switch it back to Admin mode 228 // after that. To safely switch back to Admin mode would require the 229 // caller (or other external agent) to guarantee that there are no 230 // pending ::Unwind calls. 231 232 class PriMap; 233 class SegArray; 234 class UniqueStringUniverse; 235 236 class LUL { 237 public: 238 // Create; supply a logging sink. Sets the object in Admin mode. 239 explicit LUL(void (*aLog)(const char*)); 240 241 // Destroy. Caller is responsible for ensuring that no other 242 // threads are in Unwind calls. All resources are freed and all 243 // registered unwinder threads are deregistered. Can be called 244 // either in Admin or Unwind mode. 245 ~LUL(); 246 247 // Notify the library that unwinding is now allowed and so 248 // admin-mode calls are no longer allowed. The object is initially 249 // created in admin mode. The only possible transition is 250 // admin->unwinding, therefore. 251 void EnableUnwinding(); 252 253 // Notify of a new r-x mapping, and load the associated unwind info. 254 // The filename is strdup'd and used for debug printing. If 255 // aMappedImage is NULL, this function will mmap/munmap the file 256 // itself, so as to be able to read the unwind info. If 257 // aMappedImage is non-NULL then it is assumed to point to a 258 // called-supplied and caller-managed mapped image of the file. 259 // May only be called in Admin mode. 260 void NotifyAfterMap(uintptr_t aRXavma, size_t aSize, const char* aFileName, 261 const void* aMappedImage); 262 263 // In rare cases we know an executable area exists but don't know 264 // what the associated file is. This call notifies LUL of such 265 // areas. This is important for correct functioning of stack 266 // scanning and of the x86-{linux,android} special-case 267 // __kernel_syscall function handling. 268 // This must be called only after the code area in 269 // question really has been mapped. 270 // May only be called in Admin mode. 271 void NotifyExecutableArea(uintptr_t aRXavma, size_t aSize); 272 273 // Notify that a mapped area has been unmapped; discard any 274 // associated unwind info. Acquires mRWlock for writing. Note that 275 // to avoid segfaulting the stack-scan unwinder, which inspects code 276 // areas, this must be called before the code area in question is 277 // really unmapped. Note that, unlike NotifyAfterMap(), this 278 // function takes the start and end addresses of the range to be 279 // unmapped, rather than a start and a length parameter. This is so 280 // as to make it possible to notify an unmap for the entire address 281 // space using a single call. 282 // May only be called in Admin mode. 283 void NotifyBeforeUnmap(uintptr_t aAvmaMin, uintptr_t aAvmaMax); 284 285 // Apply NotifyBeforeUnmap to the entire address space. This causes 286 // LUL to discard all unwind and executable-area information for the 287 // entire address space. 288 // May only be called in Admin mode. NotifyBeforeUnmapAll()289 void NotifyBeforeUnmapAll() { NotifyBeforeUnmap(0, UINTPTR_MAX); } 290 291 // Returns the number of mappings currently registered. 292 // May only be called in Admin mode. 293 size_t CountMappings(); 294 295 // Unwind |aStackImg| starting with the context in |aStartRegs|. 296 // Write the number of frames recovered in *aFramesUsed. Put 297 // the PC values in aFramePCs[0 .. *aFramesUsed-1] and 298 // the SP values in aFrameSPs[0 .. *aFramesUsed-1]. 299 // |aFramesAvail| is the size of the two output arrays and hence the 300 // largest possible value of *aFramesUsed. PC values are always 301 // valid, and the unwind will stop when the PC becomes invalid, but 302 // the SP values might be invalid, in which case the value zero will 303 // be written in the relevant frameSPs[] slot. 304 // 305 // This function assumes that the SP values increase as it unwinds 306 // away from the innermost frame -- that is, that the stack grows 307 // down. It monitors SP values as it unwinds to check they 308 // decrease, so as to avoid looping on corrupted stacks. 309 // 310 // May only be called in Unwind mode. Multiple threads may unwind 311 // at once. LUL user is responsible for ensuring that no thread makes 312 // any Admin calls whilst in Unwind mode. 313 // MOZ_CRASHes if the calling thread is not registered for unwinding. 314 // 315 // The calling thread must previously have been registered via a call to 316 // RegisterSampledThread. 317 void Unwind(/*OUT*/ uintptr_t* aFramePCs, 318 /*OUT*/ uintptr_t* aFrameSPs, 319 /*OUT*/ size_t* aFramesUsed, 320 /*OUT*/ size_t* aFramePointerFramesAcquired, size_t aFramesAvail, 321 UnwindRegs* aStartRegs, StackImage* aStackImg); 322 323 // The logging sink. Call to send debug strings to the caller- 324 // specified destination. Can only be called by the Admin thread. 325 void (*mLog)(const char*); 326 327 // Statistics relating to unwinding. These have to be atomic since 328 // unwinding can occur on different threads simultaneously. 329 LULStats<mozilla::Atomic<uint32_t>> mStats; 330 331 // Possibly show the statistics. This may not be called from any 332 // registered sampling thread, since it involves I/O. 333 void MaybeShowStats(); 334 335 size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const; 336 337 private: 338 // The statistics counters at the point where they were last printed. 339 LULStats<uint32_t> mStatsPrevious; 340 341 // Are we in admin mode? Initially |true| but changes to |false| 342 // once unwinding begins. 343 bool mAdminMode; 344 345 // The thread ID associated with admin mode. This is the only thread 346 // that is allowed do perform non-Unwind calls on this object. Conversely, 347 // no registered Unwinding thread may be the admin thread. This is so 348 // as to clearly partition the one thread that may do dynamic memory 349 // allocation from the threads that are being sampled, since the latter 350 // absolutely may not do dynamic memory allocation. 351 int mAdminThreadId; 352 353 // The top level mapping from code address ranges to postprocessed 354 // unwind info. Basically a sorted array of (addr, len, info) 355 // records. This field is updated by NotifyAfterMap and NotifyBeforeUnmap. 356 PriMap* mPriMap; 357 358 // An auxiliary structure that records which address ranges are 359 // mapped r-x, for the benefit of the stack scanner. 360 SegArray* mSegArray; 361 362 // A UniqueStringUniverse that holds all the strdup'd strings created 363 // whilst reading unwind information. This is included so as to make 364 // it possible to free them in ~LUL. 365 UniqueStringUniverse* mUSU; 366 }; 367 368 // Run unit tests on an initialised, loaded-up LUL instance, and print 369 // summary results on |aLUL|'s logging sink. Also return the number 370 // of tests run in *aNTests and the number that passed in 371 // *aNTestsPassed. 372 void RunLulUnitTests(/*OUT*/ int* aNTests, /*OUT*/ int* aNTestsPassed, 373 LUL* aLUL); 374 375 } // namespace lul 376 377 #endif // LulMain_h 378