platform-linux-android.cpp (18773B)
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 // Copyright (c) 2006-2011 The Chromium Authors. All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions 7 // are met: 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in 12 // the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google, Inc. nor the names of its contributors 15 // may be used to endorse or promote products derived from this 16 // software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 25 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28 // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 // SUCH DAMAGE. 30 31 // This file is used for both Linux and Android. 32 33 #include <stdio.h> 34 #include <math.h> 35 36 #include <pthread.h> 37 #if defined(GP_OS_freebsd) 38 # include <sys/thr.h> 39 #endif 40 #include <semaphore.h> 41 #include <signal.h> 42 #include <sys/time.h> 43 #include <sys/resource.h> 44 #include <sys/syscall.h> 45 #include <sys/types.h> 46 #include <stdlib.h> 47 #include <sched.h> 48 #include <ucontext.h> 49 // Ubuntu Dapper requires memory pages to be marked as 50 // executable. Otherwise, OS raises an exception when executing code 51 // in that page. 52 #include <sys/types.h> // mmap & munmap 53 #include <sys/mman.h> // mmap & munmap 54 #include <sys/stat.h> // open 55 #include <fcntl.h> // open 56 #include <unistd.h> // sysconf 57 #include <semaphore.h> 58 #ifdef __GLIBC__ 59 # include <execinfo.h> // backtrace, backtrace_symbols 60 #endif // def __GLIBC__ 61 #include <strings.h> // index 62 #include <errno.h> 63 64 #include "prenv.h" 65 #include "mozilla/PodOperations.h" 66 67 #include <string.h> 68 69 using namespace mozilla; 70 71 namespace mozilla { 72 namespace baseprofiler { 73 74 static int64_t MicrosecondsSince1970() { 75 struct timeval tv; 76 gettimeofday(&tv, NULL); 77 return int64_t(tv.tv_sec) * 1000000 + int64_t(tv.tv_usec); 78 } 79 80 void* GetStackTop(void* aGuess) { return aGuess; } 81 82 static void PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext) { 83 aRegs.mContext = aContext; 84 mcontext_t& mcontext = aContext->uc_mcontext; 85 86 // Extracting the sample from the context is extremely machine dependent. 87 #if defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android) 88 aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); 89 aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); 90 aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); 91 aRegs.mEcx = reinterpret_cast<Address>(mcontext.gregs[REG_ECX]); 92 aRegs.mEdx = reinterpret_cast<Address>(mcontext.gregs[REG_EDX]); 93 #elif defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android) 94 aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]); 95 aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]); 96 aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]); 97 aRegs.mR10 = reinterpret_cast<Address>(mcontext.gregs[REG_R10]); 98 aRegs.mR12 = reinterpret_cast<Address>(mcontext.gregs[REG_R12]); 99 #elif defined(GP_PLAT_amd64_freebsd) 100 aRegs.mPC = reinterpret_cast<Address>(mcontext.mc_rip); 101 aRegs.mSP = reinterpret_cast<Address>(mcontext.mc_rsp); 102 aRegs.mFP = reinterpret_cast<Address>(mcontext.mc_rbp); 103 aRegs.mR10 = reinterpret_cast<Address>(mcontext.mc_r10); 104 aRegs.mR12 = reinterpret_cast<Address>(mcontext.mc_r12); 105 #elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android) 106 aRegs.mPC = reinterpret_cast<Address>(mcontext.arm_pc); 107 aRegs.mSP = reinterpret_cast<Address>(mcontext.arm_sp); 108 aRegs.mFP = reinterpret_cast<Address>(mcontext.arm_fp); 109 aRegs.mLR = reinterpret_cast<Address>(mcontext.arm_lr); 110 aRegs.mR7 = reinterpret_cast<Address>(mcontext.arm_r7); 111 #elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android) 112 aRegs.mPC = reinterpret_cast<Address>(mcontext.pc); 113 aRegs.mSP = reinterpret_cast<Address>(mcontext.sp); 114 aRegs.mFP = reinterpret_cast<Address>(mcontext.regs[29]); 115 aRegs.mLR = reinterpret_cast<Address>(mcontext.regs[30]); 116 aRegs.mR11 = reinterpret_cast<Address>(mcontext.regs[11]); 117 #elif defined(GP_PLAT_arm64_freebsd) 118 aRegs.mPC = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_elr); 119 aRegs.mSP = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_sp); 120 aRegs.mFP = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_x[29]); 121 aRegs.mLR = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_lr); 122 aRegs.mR11 = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_x[11]); 123 #elif defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_mips64_android) 124 aRegs.mPC = reinterpret_cast<Address>(mcontext.pc); 125 aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[29]); 126 aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[30]); 127 128 #else 129 # error "bad platform" 130 #endif 131 } 132 133 #if defined(GP_OS_android) 134 # define SYS_tgkill __NR_tgkill 135 #endif 136 137 #if defined(GP_OS_linux) || defined(GP_OS_android) 138 int tgkill(pid_t tgid, pid_t tid, int signalno) { 139 return syscall(SYS_tgkill, tgid, tid, signalno); 140 } 141 #endif 142 143 #if defined(GP_OS_freebsd) 144 # define tgkill thr_kill2 145 #endif 146 147 class PlatformData { 148 public: 149 explicit PlatformData(BaseProfilerThreadId aThreadId) {} 150 151 ~PlatformData() {} 152 }; 153 154 //////////////////////////////////////////////////////////////////////// 155 // BEGIN Sampler target specifics 156 157 // The only way to reliably interrupt a Linux thread and inspect its register 158 // and stack state is by sending a signal to it, and doing the work inside the 159 // signal handler. But we don't want to run much code inside the signal 160 // handler, since POSIX severely restricts what we can do in signal handlers. 161 // So we use a system of semaphores to suspend the thread and allow the 162 // sampler thread to do all the work of unwinding and copying out whatever 163 // data it wants. 164 // 165 // A four-message protocol is used to reliably suspend and later resume the 166 // thread to be sampled (the samplee): 167 // 168 // Sampler (signal sender) thread Samplee (thread to be sampled) 169 // 170 // Prepare the SigHandlerCoordinator 171 // and point sSigHandlerCoordinator at it 172 // 173 // send SIGPROF to samplee ------- MSG 1 ----> (enter signal handler) 174 // wait(mMessage2) Copy register state 175 // into sSigHandlerCoordinator 176 // <------ MSG 2 ----- post(mMessage2) 177 // Samplee is now suspended. wait(mMessage3) 178 // Examine its stack/register 179 // state at leisure 180 // 181 // Release samplee: 182 // post(mMessage3) ------- MSG 3 -----> 183 // wait(mMessage4) Samplee now resumes. Tell 184 // the sampler that we are done. 185 // <------ MSG 4 ------ post(mMessage4) 186 // Now we know the samplee's signal (leave signal handler) 187 // handler has finished using 188 // sSigHandlerCoordinator. We can 189 // safely reuse it for some other thread. 190 // 191 192 // A type used to coordinate between the sampler (signal sending) thread and 193 // the thread currently being sampled (the samplee, which receives the 194 // signals). 195 // 196 // The first message is sent using a SIGPROF signal delivery. The subsequent 197 // three are sent using sem_wait/sem_post pairs. They are named accordingly 198 // in the following struct. 199 struct SigHandlerCoordinator { 200 SigHandlerCoordinator() { 201 PodZero(&mUContext); 202 int r = sem_init(&mMessage2, /* pshared */ 0, 0); 203 r |= sem_init(&mMessage3, /* pshared */ 0, 0); 204 r |= sem_init(&mMessage4, /* pshared */ 0, 0); 205 MOZ_ASSERT(r == 0); 206 (void)r; 207 } 208 209 ~SigHandlerCoordinator() { 210 int r = sem_destroy(&mMessage2); 211 r |= sem_destroy(&mMessage3); 212 r |= sem_destroy(&mMessage4); 213 MOZ_ASSERT(r == 0); 214 (void)r; 215 } 216 217 sem_t mMessage2; // To sampler: "context is in sSigHandlerCoordinator" 218 sem_t mMessage3; // To samplee: "resume" 219 sem_t mMessage4; // To sampler: "finished with sSigHandlerCoordinator" 220 ucontext_t mUContext; // Context at signal 221 }; 222 223 struct SigHandlerCoordinator* Sampler::sSigHandlerCoordinator = nullptr; 224 225 static void SigprofHandler(int aSignal, siginfo_t* aInfo, void* aContext) { 226 // Avoid TSan warning about clobbering errno. 227 int savedErrno = errno; 228 229 MOZ_ASSERT(aSignal == SIGPROF); 230 MOZ_ASSERT(Sampler::sSigHandlerCoordinator); 231 232 // By sending us this signal, the sampler thread has sent us message 1 in 233 // the comment above, with the meaning "|sSigHandlerCoordinator| is ready 234 // for use, please copy your register context into it." 235 Sampler::sSigHandlerCoordinator->mUContext = 236 *static_cast<ucontext_t*>(aContext); 237 238 // Send message 2: tell the sampler thread that the context has been copied 239 // into |sSigHandlerCoordinator->mUContext|. sem_post can never fail by 240 // being interrupted by a signal, so there's no loop around this call. 241 int r = sem_post(&Sampler::sSigHandlerCoordinator->mMessage2); 242 MOZ_ASSERT(r == 0); 243 244 // At this point, the sampler thread assumes we are suspended, so we must 245 // not touch any global state here. 246 247 // Wait for message 3: the sampler thread tells us to resume. 248 while (true) { 249 r = sem_wait(&Sampler::sSigHandlerCoordinator->mMessage3); 250 if (r == -1 && errno == EINTR) { 251 // Interrupted by a signal. Try again. 252 continue; 253 } 254 // We don't expect any other kind of failure 255 MOZ_ASSERT(r == 0); 256 break; 257 } 258 259 // Send message 4: tell the sampler thread that we are finished accessing 260 // |sSigHandlerCoordinator|. After this point it is not safe to touch 261 // |sSigHandlerCoordinator|. 262 r = sem_post(&Sampler::sSigHandlerCoordinator->mMessage4); 263 MOZ_ASSERT(r == 0); 264 265 errno = savedErrno; 266 } 267 268 Sampler::Sampler(PSLockRef aLock) : mMyPid(profiler_current_process_id()) { 269 #if defined(USE_EHABI_STACKWALK) 270 EHABIStackWalkInit(); 271 #endif 272 273 // NOTE: We don't initialize LUL here, instead initializing it in 274 // SamplerThread's constructor. This is because with the 275 // profiler_suspend_and_sample_thread entry point, we want to be able to 276 // sample without waiting for LUL to be initialized. 277 278 // Request profiling signals. 279 struct sigaction sa; 280 sa.sa_sigaction = SigprofHandler; 281 sigemptyset(&sa.sa_mask); 282 sa.sa_flags = SA_RESTART | SA_SIGINFO; 283 if (sigaction(SIGPROF, &sa, &mOldSigprofHandler) != 0) { 284 MOZ_CRASH("Error installing SIGPROF handler in the profiler"); 285 } 286 } 287 288 void Sampler::Disable(PSLockRef aLock) { 289 // Restore old signal handler. This is global state so it's important that 290 // we do it now, while gPSMutex is locked. 291 sigaction(SIGPROF, &mOldSigprofHandler, 0); 292 } 293 294 template <typename Func> 295 void Sampler::SuspendAndSampleAndResumeThread( 296 PSLockRef aLock, const RegisteredThread& aRegisteredThread, 297 const TimeStamp& aNow, const Func& aProcessRegs) { 298 // Only one sampler thread can be sampling at once. So we expect to have 299 // complete control over |sSigHandlerCoordinator|. 300 MOZ_ASSERT(!sSigHandlerCoordinator); 301 302 if (!mSamplerTid.IsSpecified()) { 303 mSamplerTid = profiler_current_thread_id(); 304 } 305 BaseProfilerThreadId sampleeTid = aRegisteredThread.Info()->ThreadId(); 306 MOZ_RELEASE_ASSERT(sampleeTid != mSamplerTid); 307 308 //----------------------------------------------------------------// 309 // Suspend the samplee thread and get its context. 310 311 SigHandlerCoordinator coord; // on sampler thread's stack 312 sSigHandlerCoordinator = &coord; 313 314 // Send message 1 to the samplee (the thread to be sampled), by 315 // signalling at it. 316 // This could fail if the thread doesn't exist anymore. 317 int r = tgkill(mMyPid.ToNumber(), sampleeTid.ToNumber(), SIGPROF); 318 if (r == 0) { 319 // Wait for message 2 from the samplee, indicating that the context 320 // is available and that the thread is suspended. 321 while (true) { 322 r = sem_wait(&sSigHandlerCoordinator->mMessage2); 323 if (r == -1 && errno == EINTR) { 324 // Interrupted by a signal. Try again. 325 continue; 326 } 327 // We don't expect any other kind of failure. 328 MOZ_ASSERT(r == 0); 329 break; 330 } 331 332 //----------------------------------------------------------------// 333 // Sample the target thread. 334 335 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 336 // 337 // The profiler's "critical section" begins here. In the critical section, 338 // we must not do any dynamic memory allocation, nor try to acquire any lock 339 // or any other unshareable resource. This is because the thread to be 340 // sampled has been suspended at some entirely arbitrary point, and we have 341 // no idea which unsharable resources (locks, essentially) it holds. So any 342 // attempt to acquire any lock, including the implied locks used by the 343 // malloc implementation, risks deadlock. This includes TimeStamp::Now(), 344 // which gets a lock on Windows. 345 346 // The samplee thread is now frozen and sSigHandlerCoordinator->mUContext is 347 // valid. We can poke around in it and unwind its stack as we like. 348 349 // Extract the current register values. 350 Registers regs; 351 PopulateRegsFromContext(regs, &sSigHandlerCoordinator->mUContext); 352 aProcessRegs(regs, aNow); 353 354 //----------------------------------------------------------------// 355 // Resume the target thread. 356 357 // Send message 3 to the samplee, which tells it to resume. 358 r = sem_post(&sSigHandlerCoordinator->mMessage3); 359 MOZ_ASSERT(r == 0); 360 361 // Wait for message 4 from the samplee, which tells us that it has 362 // finished with |sSigHandlerCoordinator|. 363 while (true) { 364 r = sem_wait(&sSigHandlerCoordinator->mMessage4); 365 if (r == -1 && errno == EINTR) { 366 continue; 367 } 368 MOZ_ASSERT(r == 0); 369 break; 370 } 371 372 // The profiler's critical section ends here. After this point, none of the 373 // critical section limitations documented above apply. 374 // 375 // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 376 } 377 378 // This isn't strictly necessary, but doing so does help pick up anomalies 379 // in which the signal handler is running when it shouldn't be. 380 sSigHandlerCoordinator = nullptr; 381 } 382 383 // END Sampler target specifics 384 //////////////////////////////////////////////////////////////////////// 385 386 //////////////////////////////////////////////////////////////////////// 387 // BEGIN SamplerThread target specifics 388 389 static void* ThreadEntry(void* aArg) { 390 auto thread = static_cast<SamplerThread*>(aArg); 391 thread->Run(); 392 return nullptr; 393 } 394 395 SamplerThread::SamplerThread(PSLockRef aLock, uint32_t aActivityGeneration, 396 double aIntervalMilliseconds, uint32_t aFeatures) 397 : mSampler(aLock), 398 mActivityGeneration(aActivityGeneration), 399 mIntervalMicroseconds( 400 std::max(1, int(floor(aIntervalMilliseconds * 1000 + 0.5)))) { 401 // Start the sampling thread. It repeatedly sends a SIGPROF signal. Sending 402 // the signal ourselves instead of relying on itimer provides much better 403 // accuracy. 404 if (pthread_create(&mThread, nullptr, ThreadEntry, this) != 0) { 405 MOZ_CRASH("pthread_create failed"); 406 } 407 } 408 409 SamplerThread::~SamplerThread() { pthread_join(mThread, nullptr); } 410 411 void SamplerThread::SleepMicro(uint32_t aMicroseconds) { 412 if (aMicroseconds >= 1000000) { 413 // Use usleep for larger intervals, because the nanosleep 414 // code below only supports intervals < 1 second. 415 MOZ_ALWAYS_TRUE(!::usleep(aMicroseconds)); 416 return; 417 } 418 419 struct timespec ts; 420 ts.tv_sec = 0; 421 ts.tv_nsec = aMicroseconds * 1000UL; 422 423 int rv = ::nanosleep(&ts, &ts); 424 425 while (rv != 0 && errno == EINTR) { 426 // Keep waiting in case of interrupt. 427 // nanosleep puts the remaining time back into ts. 428 rv = ::nanosleep(&ts, &ts); 429 } 430 431 MOZ_ASSERT(!rv, "nanosleep call failed"); 432 } 433 434 void SamplerThread::Stop(PSLockRef aLock) { 435 // Restore old signal handler. This is global state so it's important that 436 // we do it now, while gPSMutex is locked. It's safe to do this now even 437 // though this SamplerThread is still alive, because the next time the main 438 // loop of Run() iterates it won't get past the mActivityGeneration check, 439 // and so won't send any signals. 440 mSampler.Disable(aLock); 441 } 442 443 // END SamplerThread target specifics 444 //////////////////////////////////////////////////////////////////////// 445 446 #if defined(GP_OS_linux) || defined(GP_OS_freebsd) 447 448 // We use pthread_atfork() to temporarily disable signal delivery during any 449 // fork() call. Without that, fork() can be repeatedly interrupted by signal 450 // delivery, requiring it to be repeatedly restarted, which can lead to *long* 451 // delays. See bug 837390. 452 // 453 // We provide no paf_child() function to run in the child after forking. This 454 // is fine because we always immediately exec() after fork(), and exec() 455 // clobbers all process state. Also, we don't want the sampler to resume in the 456 // child process between fork() and exec(), it would be wasteful. 457 // 458 // Unfortunately all this is only doable on non-Android because Bionic doesn't 459 // have pthread_atfork. 460 461 // In the parent, before the fork, increase gSkipSampling to ensure that 462 // profiler sampling loops will be skipped. There could be one in progress now, 463 // causing a small delay, but further sampling will be skipped, allowing `fork` 464 // to complete. 465 static void paf_prepare() { ++gSkipSampling; } 466 467 // In the parent, after the fork, decrease gSkipSampling to let the sampler 468 // resume sampling (unless other places have made it non-zero as well). 469 static void paf_parent() { --gSkipSampling; } 470 471 static void PlatformInit(PSLockRef aLock) { 472 // Set up the fork handlers. 473 pthread_atfork(paf_prepare, paf_parent, nullptr); 474 } 475 476 #else 477 478 static void PlatformInit(PSLockRef aLock) {} 479 480 #endif 481 482 #if defined(HAVE_NATIVE_UNWIND) 483 // TODO port getcontext from breakpad, if profiler_get_backtrace is needed. 484 # define REGISTERS_SYNC_POPULATE(regs) \ 485 MOZ_CRASH("profiler_get_backtrace() unsupported"); 486 #endif 487 488 } // namespace baseprofiler 489 } // namespace mozilla