void ah_crap_handler(int signum) { printf("\nProgram %s (pid = %d) received signal %d.\n", _progname, getpid(), signum); printf("Stack:\n"); MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, nullptr, 0, nullptr); printf("Sleeping for %d seconds.\n",_gdb_sleep_duration); printf("Type 'gdb %s %d' to attach your debugger to this thread.\n", _progname, getpid()); // Allow us to be ptraced by gdb on Linux with Yama restrictions enabled. prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY); sleep(_gdb_sleep_duration); printf("Done sleeping...\n"); _exit(signum); }
void nsTraceRefcnt::WalkTheStack(FILE* aStream) { #ifdef MOZ_STACKWALKING MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, aStream, 0, nullptr); #endif }
/** * This is a variant of |WalkTheStack| that uses |CodeAddressService| to cache * the results of |NS_DescribeCodeAddress|. If |WalkTheStackCached| is being * called frequently, it will be a few orders of magnitude faster than * |WalkTheStack|. However, the cache uses a lot of memory, which can cause * OOM crashes. Therefore, this should only be used for things like refcount * logging which walk the stack extremely frequently. */ static void WalkTheStackCached(FILE* aStream) { if (!gCodeAddressService) { gCodeAddressService = new WalkTheStackCodeAddressService(); } MozStackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0, aStream, 0, nullptr); }
void nsTraceRefcnt::WalkTheStackCached(FILE* aStream) { #ifdef MOZ_STACKWALKING if (!gCodeAddressService) { gCodeAddressService = new WalkTheStackCodeAddressService(); } MozStackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0, aStream, 0, nullptr); #endif }
static void SandboxLogCStack() { // Skip 3 frames: one for this module, one for the signal handler in // libmozsandbox, and one for the signal trampoline. // // Warning: this might not print any stack frames. MozStackWalk // can't walk past the signal trampoline on ARM (bug 968531), and // x86 frame pointer walking may or may not work (bug 1082276). MozStackWalk(SandboxPrintStackFrame, /* skip */ 3, /* max */ 0, nullptr); SANDBOX_LOG_ERROR("end of stack."); }
static void WalkTheStackSavingLocations(std::vector<void*>& aLocations) { if (!gCodeAddressService) { gCodeAddressService = new WalkTheStackCodeAddressService(); } static const int kFramesToSkip = 0 + // this frame gets inlined 1 + // GetSerialNumber 1; // NS_LogCtor MozStackWalk(RecordStackFrame, kFramesToSkip, /* maxFrames */ 0, &aLocations, 0, nullptr); }
static void GetChromeHangReport(Telemetry::ProcessedStack& aStack, int32_t& aSystemUptime, int32_t& aFirefoxUptime) { MOZ_ASSERT(winMainThreadHandle); // The thread we're about to suspend might have the alloc lock // so allocate ahead of time std::vector<uintptr_t> rawStack; rawStack.reserve(MAX_CALL_STACK_PCS); DWORD ret = ::SuspendThread(winMainThreadHandle); if (ret == -1) { return; } MozStackWalk(ChromeStackWalker, /* skipFrames */ 0, /* maxFrames */ 0, reinterpret_cast<void*>(&rawStack), reinterpret_cast<uintptr_t>(winMainThreadHandle), nullptr); ret = ::ResumeThread(winMainThreadHandle); if (ret == -1) { return; } aStack = Telemetry::GetStackAndModules(rawStack); // Record system uptime (in minutes) at the time of the hang aSystemUptime = ((GetTickCount() / 1000) - (gTimeout * 2)) / 60; // Record Firefox uptime (in minutes) at the time of the hang bool error; TimeStamp processCreation = TimeStamp::ProcessCreation(error); if (!error) { TimeDuration td = TimeStamp::Now() - processCreation; aFirefoxUptime = (static_cast<int32_t>(td.ToSeconds()) - (gTimeout * 2)) / 60; } else { aFirefoxUptime = -1; } }
void nsTraceRefcnt::WalkTheStack(FILE* aStream) { MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, aStream, 0, nullptr); }