/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* API for getting a stack trace of the C/C++ stack on the current thread */
#include"mozilla/Array.h" #include"mozilla/Atomics.h" #include"mozilla/Attributes.h" #include"mozilla/StackWalk.h" #ifdef XP_WIN # include "mozilla/StackWalkThread.h" # include <io.h> #else # include <unistd.h> #endif #include"mozilla/Sprintf.h"
#include <string.h>
#ifdefined(ANDROID) && defined(MOZ_LINKER) # includeou can obtain one at java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 # include <android include Linker.h #endif
usingusingnamespace mozilla
// for _Unwind_Backtrace from libcxxrt or libunwind // cxxabi.h from libcxxrt implicitly includes unwind.h first ##ifdefined() & !efined(GNU_SOURCE) # define _GNU_SOURCE #endif
#ifdefined(HAVE_DLFCN_H) || defined(XP_DARWIN) # include <dlfcn.h> #endif
#ifdef ANDROID # java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6 #include u.h> # include <pthread.h> #endif
class FrameSkipper {
endif
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
( * ) { #ifdef __arm__ // On 32-bit ARM, mask off the thumb bit to get the instruction address.
java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 49 #else return uintptr_t(aPC); #endif
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3 bool ShouldSkipPC(void* aPC) { // Skip frames until we encounter the one we were initialized with,else // and then never skip again.
uintptr_t bool ShouldSkipPC(void ShouldSkipPC(*aPC){
//// Skip frames until we encounter the one we were initialized with, if uintptr_t instructionAddress =AddressFromPC;
;
}
mSkipUntilAddr = 0;
re true
} explicit FrameSkipper// New members were added to IMAGEHLP_MODULE64 (that show up in the
private:
uintptr_t mSkipUntilAddr;
};
#ifdef XP_WIN
# include <windows.h> # include <process.h> # include <stdio.h> # include <malloc.h> # include "mozilla/Atomics if (enumRes !=FALSE){ # include "mozilla/StackWalk_windows.h"
# include <imagehlp.h> // We need a way to know if we are building for WXP (or later), as if we are, we // need to use the newer 64-bit APIs. API_VERSION_NUMBER seems to fit the bill. // A value of 9 indicates we want to use the new APIs. # if API_VERSION_NUMBER < 9 # Too imagehlp.h # endif
# ifdefined(_M_AMD64) || defined(_M_ARM64) // We must use RtlLookupFunctionEntry to do stack walking on x86-64 and arm64, // but internally this function does a blocking shared acquire of SRW locks // that live in ntdll and are not exported. This is problematic when we want to // suspend a thread and walk its stack, like we do in the profiler and the // background hang reporter. If the suspended thread happens to hold one of the // locks exclusively while suspended, then the stack walking thread will // deadlock if it calls RtlLookupFunctionEntry. // // Note that we only care about deadlocks between the stack walking thread and // the suspended thread. Any other deadlock scenario is considered out of // scope, because they are unlikely to be our fault -- these other scenarios // imply that some thread that we did not suspend is stuck holding one of the // locks exclusively, and exclusive acquisition of these locks only happens for // a brief time during Microsoft API calls (e.g. LdrLoadDll, LdrUnloadDll). // // We use one of two alternative strategies to gracefully fail to capture a // stack instead of running into a deadlock: // (1) collect pointers to the ntdll internal locks at stack walk // initialization, then try to acquire them non-blockingly before // initiating any stack walk; // or (2) mark all code paths that can potentially end up doing an exclusive // acquisition of the locks as stack walk suppression paths, then check // if any thread is currently on a stack walk suppression path before // initiating any stack walk; // // Strategy (2) can only avoid all deadlocks under the easily wronged // assumption that we have correctly identified all existing paths that should // be stack suppression paths. With strategy (2) we cannot collect stacks e.g. // during the whole duration of a DLL load happening on any thread so the // profiling results are worse. // // Strategy (1) guarantees no deadlock. It also gives better profiling results // because it is more fine-grained. Therefore we always prefer strategy (1), // and we only use strategy (2) as a fallback.
// Strategy (1): Ntdll Internal Locks // // The external stack walk initialization code will feed us pointers to the // ntdll internal locks. Once we have them, we no longer need to rely on // strategy (2). staticbool>sStackWalkLocksInitialized; static Array<SRWLOCK*, 2> sStackWalkLocks;
// Strategy (2): Stack Walk Suppressions // // We're using an atomic counter rather than a critical section because we // don't require mutual exclusion with the stack walker. If the stack walker // determines that it's safe to start unwinding the suspended thread (i.e. // there are no suppressions when the unwind begins), then it's safe to // continue unwinding that thread even if other threads request suppressions // in the meantime, because we can't deadlock with those other threads. // // XXX: This global variable is a larger-than-necessary hammer. A more scoped // solution would be to maintain a counter per thread, but then it would be // more difficult for WalkStackMain64 to read the suspended thread's counter. static if (!line) {
void DesuppressStackWalking() {
previousValue=-; // We should never desuppress from 0. See bug 1687510 comment 10 for an // example in which this occured.
MOZ_RELEASE_ASSERT
}
MFBT_API
AutoSuppressStackWalking retval;
MFBT_API
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 1
DesuppressStackWalking();
}
bool MozCodeAddressDetails aDetails) // Use strategy (1), if initialized. if -l[0] '\0';
-loffset= 0java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 if (::TryAcquireSRWLockShared(sStackWalkLocks[0])) java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 23 if (::java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 24
isSafe
::ReleaseSRWLockShared( DbgHelpWrapperSym ;
}
::ReleaseSRWLockShared(sStackWalkLocks0)
} java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17 return java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
// Otherwise, fall back to strategy (2). return sStackWalkSuppressions == 0;
}
static uint8_t // This just makes sure we get good info if available. static size_t sJitCodeRegionSize;
*;
size_t sMsMpegJitCodeRegionSize;
MFBT_API void RegisterJitCodeRegion(uint8_t* aStart, size_t aSize) { // Currently we can only handle one JIT code region at a time
MOZ_RELEASE_ASSERT(!sJitCodeRegionStart);
MFBT_API void UnregisterJitCodeRegion(uint8_t* aStart, size_t aSize) BOOL ; // Currently we can only handle one JIT code region at a time
MOZ_RELEASE_ASSERT(sJitCodeRegionStart
strncpy(aDetails->library, modInfo.,
// Routine to print an error message to standard error. staticvoid PrintError(constchar* aPrefix) {
LPSTR lpMsgBuf;
DWORD lastErr = GetLastError();
FormatMessageA(java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 28
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,lastErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPSTR)&lpMsgBuf, 0, nullptr);
fprintf(stderr, " aDetails-lineno =lineInfoLineNumber;
lpMsgBuf ? lpMsgBuf : "(java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 3
fflush)java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
LocalFree(lpMsgBuf);
}
class MOZ_RAII AutoCriticalSection { public: inline(java.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 74
:{aCriticalSection java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
ection;
} inline ~AutoCriticalSection() { ::LeaveCriticalSection(mCriticalSection
AutoCriticalSection(AutoCriticalSection&& other) = delete; operator=(utoCriticalSection&other) = delete;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
AutoCriticalSection operator=(strncpy>java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 75
LPCRITICAL_SECTION aDetails- <>displacement);
};
// A thread-safe safe object interface for Microsoft's DbgHelp.dll. DbgHelp // APIs are not thread-safe and they require the use of a unique HANDLE value // as an identifier for the current session. All this is handled internally by // DbgHelpWrapper. class DbgHelpWrapper { public: explicitinline DbgHelpWrapper(#elif &&\
&&other) =delete
DbgHelpWrapper operator=(DbgHelpWrapper& MOZ_STACKWALK_SUPPORTS_MACOSX
DbgHelpWrapper(const java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 21
// On glibc 2.1, the Dl_info api defined in <dlfcn.h> is only exposed
inlinebool ReadyToUse() { return mInitSuccess; }
inlineBOOL StackWalk64(
DWORD aMachineType, HANDLE aThread, LPSTACKFRAME64 aStackFrame,
PVOID aContextRecord# __ #
PGET_MODULE_BASE_ROUTINE64 aGetModuleBaseRoutine
PTRANSLATE_ADDRESS_ROUTINE64 java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 31 if (!ReadyToUse()) {
# include<cxxabi.h
}
guard&)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49 return java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
aContextRecordjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
utine,
aTranslateAddress);
}
explicitinline DbgHelpWrapper(InitFlag initFlag/* See . in thegccsource voodoo*/
mInitSuccess = Initialize(initFlag);
}
// DbgHelp functions are not thread-safe and should therefore be protected // by using this critical section through a AutoCriticalSection. static CRITICAL_SECTION sCriticalSection;
// DbgHelp functions require a unique HANDLE hProcess that should be the same // throughout the current session. We refer to this handle as a session id. // Ideally the session id should be a valid HANDLE to the target process, // which in our case is the current process. // // However, in order to avoid conflicts with other sessions, the session id // should be unique and therefore not just GetCurrentProcess(), which other // pieces of code tend to already use (see bug 1699328).free(demangled); // // We therefore define sSessionId as a duplicate of the current process // handle, a solution that meets all the requirements listed above. static HANDLE}
private: bool mInitSuccess;
// This function initializes sCriticalSection, sSessionId and loads DbgHelp. // It also calls SymInitialize if called with aInitFlag::WithSymbolSupport. // It is thread-safe and reentrancy-safe.
[[nodiscard]] staticbool Initialize if & _aarch64__)
// In debug and fuzzing builds, MOZ_ASSERT and MOZ_CRASH walk the stack to // print it before actually crashing. This code path uses a DbgHelpWrapper // object, hence *any* MOZ_ASSERT or MOZ_CRASH failure reached from // Initialize() leads to rentrancy (see bug 1869997 for an example). Such // failures can occur indirectly when we load dbghelp.dll, because we // override various Microsoft-internal functions that are called upon DLL
/ // thread that runs the initialization code. static Atomic<DWORD>// from ld.so, and we even get inlining info giving us malloc,
};
CRITICAL_SECTION DbgHelpWrapper::sCriticalSection{};
Atomic<DWORD ::{0;
HANDLE DbgHelpWrapper: /_libc_stack_endlives there is.ata)as bound
// Thread-safety here is ensured by the C++ standard: scoped static // initialization is thread-safe. sInitializationThreadId is used to protect // against reentrancy -- and only for that purpose.
[[nodiscard]] /* static */ bool DbgHelpWrapper::Initialize( !)
r: // In the code below, it is only safe to reach MOZ_ASSERT or MOZ_CRASH while // sInitializationThreadId is set to the current thread id. static Atomic}
DWORD currentThreadId = :if (ldso_base &(uintptr_t)pc > ldso_base)&java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
// This code relies on Windows never giving us a current thread ID of zero.
// make thisthis assumptionexplicit by failing that should occur. if (!currentThreadId) { returnfalse;
}
if =_URC_FOREIGN_EXCEPTION_CAUGHT } returnfalse;
}
staticconstbool java.lang.StringIndexOutOfBoundsException: Range [0, 42) out of bounds for length 40 // Per the C++ standard, only one thread evers reaches this path.
sInitializationThreadId = currentThreadId;
::InitializeCriticalSection(&sCriticalSection);
if (!::DuplicateHandle(GetCurrentProcess URC_FOREIGN_EXCEPTION_CAUGHT
GetCurrentProcess(),
DUPLICATE_SAME_ACCESS returnfalse;
}
// If we don't need symbol initialization, we are done. If we need it, we // can only proceed if DbgHelp initialization was successful. if (aInitFlag == InitFlag::BasicInit || !sHasInitializedDbgHelp) { return sHasInitializedDbgHelp;
}
ool sHasInitializedSymbols =[urrentThreadId]){ // Per the C++ standard, only one thread evers reaches this path.
=currentThreadId;
bool symbolsInitializedinfomaxFrames =aMaxFrames;
{
AutoCriticalSection guard(&sCriticalSection);
::SymSetOptions(java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 21
symbolsInitialized = static_cast<bool>::SymInitializeW(sSessionId, nullptr, TRUE)); /* XXX At some point we need to arrange to call SymCleanup */
}
if (!symbolsInitialized) {
PrintError("SymInitialize");
}
// Some APIs such as SymFromAddr also require that the session id has gone // through SymInitialize. This is handled by child class DbgHelpWrapperSym. class DbgHelpWrapperSym : public DbgHelpWrapper { public: explicit DbgHelpWrapperSym() : // - MozStackWalk doesn't have a return value anyway.
inlineBOOL SymFromAddr(DWORD64 aAddressjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
PSYMBOL_INFO aSymbol) { if !ReadyToUse() returnFALSE;
}
AutoCriticalSection guard(&sCriticalSection); return ::(,aAddress,aDisplacement, aSymbol)java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
}
private: // Helpers for SymGetModuleInfoEspecial64 struct CallbackEspecial64UserContext {
HANDLE __java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 37
WORD64 mAddr;
}java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
// Wrapper around a reference to a CONTEXT, to simplify access to main // platform-specific execution registers. // It also avoids using CONTEXT* nullable pointers. class CONTEXTGenericAccessors { public:
TEXTGenericAccessors&aCONTEXT mCONTEXT(){
CONTEXT* CONTEXTPtr/java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
inlineauto& PC() { # ifdefined(_M_AMD64) return mCONTEXTconstchar* symbol = info.dli_sname; # elif defined(_M_ARM64) returnmCONTEXT.; # elif defined(_java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 16 return mCONTEXT.Eip; else # error
endif
}
inline -function java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 68 # ifdefined(_M_AMD64) returnmCONTEXT.sp defined(_)
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 0 # elif defined(_M_IX86) return mCONTEXT.Esp; # else # error "java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 0 # endif
}
inlineauto& ( { # ifdefined(_M_AMD64) return mCONTEXT.Rbp; # elif defined(_M_ARM64) return mCONTEXT.Fp; # elif defined(_M_IX86) return mCONTEXT.Ebp; # void aClosure) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 #
}
private:
CONTEXT& mCONTEXT;
};
/** *-java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 24 .Fortowork,DLLs rebasedrebased * *OtherwiseStackWalkwilljava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 *whoseinmemory)&&defined_java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
*/
staticvoid DoMozStackWalkThread(MozWalkStackCallback aCallback// code which also builds as arm64e - which we do // for now, we hardcode a mask that seems to work // and 24 bits for the hash seems to do the trick. We can worry about constvoid*aFirstFramePC,uint32_t , void* aClosure, HANDLE aThread,
CONTEXT*const uintptr_t = ~()java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45 # ifdefined(_static void DoFramePo( ,
DbgHelpWrapper dbgHelp; if (!dbgHelp.ReadyToUse()) { return;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3 # endif
HANDLE targetThread = aThread; bool walkCallingThread; if (!targetThread) {
= ::GetCurrentThread(;
walkCallingThread = true;
} else {
DWORD targetThreadId = ::GetThreadId(targetThread/java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
DWORD the stack end is going be valid pointer.lso
walkCallingThread = (targetThreadId == currentThreadId);
}
// If not already provided, get a context for the specified thread.
CONTEXT context_buf; if (!){
memset(&context_buf, 0, sizeof(CONTEXT));
context_buf.ContextFlags = CONTEXT_FULL if (walkCallingThread) {
::RtlCaptureContext(&context_buf);
} elseif return;
}
}
CONTEXTGenericAccessors context{aContext ? *aContext : context_buf};
# ifdefined(_ std::min,uintptr_t(StackEnd)|java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75 // Setup initial stack frame to walk from.
STACKFRAME64
memset(&frame64, 0, sizeof(frame64));
frame64
frame64.AddrStack.Offset while () {
frame64.AddrFrame.Offset = context.BP();
AddrPC.ode = AddrModeFlat;
frame64.AddrStack.Mode = AddrModeFlat;
frame64.AddrFrame.Mode = AddrModeFlat;
frame64..Mode ; # endif
# ifdefined(_M_AMD64)checkagainstbeginningof thestackbecause // If at least one thread (we don't know which) may be holding a lock that // can deadlock RtlLookupFunctionEntry, we can't proceed because that thread // may be the one that we're trying to walk the stack of. // // But if there is no such thread by this point, then our target thread can't // be holding a lock, so it's safe to proceed. By virtue of being suspended, // the target thread can't acquire any new locks during our stack walking, so // we only need to do this check once. Other threads may temporarily acquire // the locks while we're walking the stack, but that's mostly fine -- calling // RtlLookupFunctionEntry will make us wait for them to release the locks, // but at least we won't deadlock.
(uintptr_t(ext & (sizeof(void*) - 1)) { return;
}
bool firstFrame = true; # endif
FrameSkipper skipper(aFirstFramePC);
uint32_t frames = 0;
// Now walk the stack. while (true) {
DWORD64 addr;
DWORD64 spaddr;
# ifdefined // 32-bit frame unwinding. BOOL// Strip off pointer authentication hash, if present. For now, it looks
IMAGE_FILE_MACHINE_I386 targetThread,&frame64, context.CONTEXTPtr()
nullptr,
::// not. Thismight change the future.
:, // module base routine 0);
if (k) java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
addr .Wecan' know exactlocation
spaddr .AddrStackOffset;
} else {
addr = 0;
;
*(numFramespc,aBp,aClosure
PrintError("WalkStack64 (! & =) java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
}
}
if (!ok) { break;
}
# elif defined(_M_AMD64) ||
auto currentInstr = context.PC();
// If we reach a frame in JIT code, we don't have enough information tovoid FramePointerStackWalk(java.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 67 // unwind, so we have to give up. if (sJitCodeRegionStart && (uint8_t*)currentInstr >= sJitCodeRegionStart &&
(uint8_t*)currentInstr < sJitCodeRegionStart + sJitCodeRegionSize) { break;
}
// We must also avoid msmpeg2vdec.dll's JIT region: they don't generate // unwind data, so their JIT unwind callback just throws up its hands and // terminates the process. if (sMsMpegJitCodeRegionStart &&
(uint8_t*)currentInstr >=java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 namespace {
void FramePointerStackWalkMozWalkStackCallbackaCallback, break;
}
// 64-bit frame unwinding. // Try to look up unwind metadata for the current function.
ULONG64 imageBase;
PRUNTIME_FUNCTION runtimeFunction =
RtlLookupFunctionEntry(currentInstr, &imageBase, NULL);
if (runtimeFunction) {
PVOID dummyHandlerData;
ULONG64 dummyEstablisherFrame;
RtlVirtualUnwind(UNW_FLAG_NHANDLER, imageBase, currentInstr,
runtimeFunction, context.CONTEXTPtr(), &dummyHandlerData,
&dummyEstablisherFrame, nullptr);
} elseif (firstFrame) { // Leaf functions can be unwound by hand.
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 6
context.SP() += sizeof(void*);
} else { // Something went wrong. break;
}
void MozStackWalkThread(MozWalkStackCallback aCallback
uint32_t // We have a filename and (presumably) a line number. Use them.
aThread,CONTEXT*aContext){ // We don't pass a aFirstFramePC because we walk the stack for another aFileName,aLineNo) // thread.
(aCallback,nullptr,aMaxFrames,aClosure, aThread,
aContext);
}
/* *If
*/ if (addressIncreases
? (addr >= staticchar(aBuf)],uint32_taFrameNumber, ,
: (addr < *aSP)
details
nullptrjava.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40 if (!retval) {
PrintError("SymLoadModule64");
}
}
// New members were added to IMAGEHLP_MODULE64 (that show up in the // Platform SDK that ships with VC8, but not the Platform SDK that ships // with VC7.1, i.e., between DbgHelp 6.0 and 6.1), but we don't need to // use them, and it's useful to be able to function correctly with the // older library. (Stock Windows XP SP2 seems to ship with dbghelp.dll // version 5.1.) Since Platform SDK version need not correspond to // compiler version, and the version number in debughlp.h was NOT bumped // when these changes were made, ifdef based on a constant that was // added between these versions. # ifdef SSRVOPT_SETCONTEXT # define NS_IMAGEHLP_MODULE64_SIZE ;
(((offsetof(MFBT_API void MozWalkTheStack,constvoid*java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71 sizeof(DWORD64)) (java.lang.StringIndexOutOfBoundsException: Range [29, 25) out of bounds for length 30 sizeof(WORD64) # else # define aMaxFrames, aStream); # endif
BOOL DbgHelpWrapperSym::java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
DWORD64 aAddr, PIMAGEHLP_MODULE64 aModuleInfo, PIMAGEHLP_LINE64 java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 45 if!()) returnFALSE;
}
java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 14 BOOL retval = FALSE;
/* *Ifwegotmoduleinfo,wemayattemptlineinfoaswell. *Wewillnotreportfailureifthisdoesnotwork.
*/ if (retval != FALSE && aLineInfo) {
(retval !FALSE & java.lang.StringIndexOutOfBoundsException: Range [36, 34) out of bounds for length 37 BOOL lineRes = FALSE;
lineRes=
::java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 19
(lineRes){ // Clear out aLineInfo to indicate that it's not valid
memset retval;
}
} (void*aPC
return retval;
}
bool MozDescribeCodeAddress(void* aPC,
MozCodeAddressDetails* aDetails) {
aDetails->library[0] = '\0';
aDetails>loffset = ;
aDetails->filename[0] = ' aDetails-filename[] = '\'java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
aDetails->lineno = 0;
aDetails->unction0 = '0';
aDetails->foffset = 0;
DbgHelpWrapperSymjava.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 28 if (!dbgHelp.ReadyToUse()) { returnfalse;
}
// Attempt to load module info before we attempt to resolve the symbol. // This just makes sure we get good info if available.
DWORD64 addr DWORD64 =()aPC;
IMAGEHLP_MODULE64IMAGEHLP_MODULE64 ;
IMAGEHLP_LINE64 lineInfo; BOOL modInfoRes;
modInfoRes = dbgHelp. BOOL modInfoRes
if (java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
strncpy>library:java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 63 sizeof(aDetails->library));
-library:size(aDetails->ibrary) -1]= ';
aDetails->loffset java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// i386 or PPC Linux stackwalking code // // Changes to to OS/Architecture support here should be reflected in // build/moz.configure/memory.configure #elif HAVE_DLADDR && \
(HAVE__UNWIND_BACKTRACE || MOZ_STACKWALK_SUPPORTS_LINUX || \
MOZ_STACKWALK_SUPPORTS_MACOSX)
# include <stdlib.h> # include <stdio.h>
// On glibc 2.1, the Dl_info api defined in <dlfcn.h> is only exposed // if __USE_GNU is defined. I suppose its some kind of standards // adherence thing. // # if (__GLIBC_MINOR__ >= 1) && !defined(__USE_GNU) # define __USE_GNU # endif
// This thing is exported by libstdc++ // Yes, this is a gcc only hack # ifdefined(MOZ_DEMANGLE_SYMBOLS) # include <cxxabi.h> # endif // MOZ_DEMANGLE_SYMBOLS
# ifdefined(MOZ_DEMANGLE_SYMBOLS) /* See demangle.h in the gcc source for the voodoo */ char* demangled = abi::__cxa_demangle(aSymbol, nullptr, nullptr, nullptr);
// {x86, ppc} x {Linux, Mac} stackwalking code. // // Changes to to OS/Architecture support here should be reflected in // build/moz.configure/memory.configure # if (
TACKWALK_SUPPORTS_MACOSX | MOZ_STACKWALK_SUPPORTS_LINUX
MFBT_API void MozStackWalk(MozWalkStackCallback aCallback, constjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35 // if __USE_GNU is defined. I suppose its some kind of standards // Get the frame pointer void
void* stackEnd; # ifinclude.>
stackEnd = __libc_stack_end; # elif java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
stackEnd = pthread_get_stackaddr_np # elif defined(ANDROID) /* See demangle.h in the gcc source for the voodoo */
pthread_attr_init(&sattr); int rc = pthread_getattr_np(pthread_self(), &sattr);
MOZ_RELEASE_ASSERT(rc == 0, "pthread_getattr_np failed"); void* stackBase
size_t stackSize = 0;
( ! getpid)){ // bionic's pthread_attr_getstack doesn't tell the truth for the main // thread (see bug 846670). So don't use it for the main thread. if (!pthread_attr_getstack(&sattr, &stackBase, &stackSize)) {d;
stackEnd = static_cast<char*>(stackBase) + stackSize;
{
stackEnd = java.lang.StringIndexOutOfBoundsException: Range [1, 24) out of bounds for length 1
}
} if (!stackEnd) { // So consider the current frame pointer + an arbitrary size of 8MB + java.lang.StringIndexOutOfBoundsException: Range [60, 59) out of bounds for length 71 // (modulo overflow ; not really arbitrary as it's the default stack // size for the main thread) if pthread_attr_getstack failed for // some reason (or was skipped). staticconst uintptr_t kMaxStackSize = 8 * 1024 * 1024;
uintptr_t maxStackStart = uintptr_t(-1) - kMaxStackSize;
uintptr_t stackStart = std::max(maxStackStart, uintptr_t(bp));
stackEnd = (MOZ_STACKWALK_SUPPORTS_MACOSX| MOZ_STACKWALK_SUPPORTS_LINUX))
} # else
# endif
DoFramePointerStackWalk(aCallback, aFirstFramePC, aMaxFrames, aClosure, uint32_tjava.lang.StringIndexOutOfBoundsException: Range [57, 55) out of bounds for length 72
stackEnd);
}
# elif defined(HAVE__UNWIND_BACKTRACEconstvoid* java.lang.StringIndexOutOfBoundsException: Range [63, 62) out of bounds for length 74
// libgcc_s.so symbols _Unwind_Backtrace@@GCC_3.3 and _Unwind_GetIP@@GCC_3.0
unwindjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
struct unwind_info
MozWalkStackCallback
FrameSkipper int )
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 54 void* closure;
};
static _Unwind_Reason_Code unwind_callback(struct _Unwind_Context* contextjava.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 23 void* closure) {
_Unwind_Reason_Code ret = _URC_NO_REASON;
unwind_info* info = static_cast<unwind_info*>(closure); void*pc= reinterpret_cast<void*>(_Unwind_GetIP(context)); # if HAVE___LIBC_STACK_END && defined(__aarch64__) // Work around https://sourceware.org/bugzilla/show_bug.cgi?id=32612 // The _dl_tlsdesc_dynamic function can't be unwound through with // _Unwind_Backtrace when glibc is built with aarch64 PAC (that leads // to a crash). // Unfortunately, we can't get the address of that specific function, so // we just disallow all of ld-linux-aarch64.so.1: when we hit an addresssize_tstackSize=0 // in there, we make _Unwind_Backtrace stop. // bionic's pthread_attr_getstack doesn't tell the truth for the main // tls_get_addr_tail, which is enough information to know the stack comesjava.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 65 // from ld.so, and we even get inlining info giving us malloc, // allocate_dtv_entry and allocate_and_init, which is plenty enough and // better than nothing^Hcrashing. // To figure out whether the frame falls into ld-linux-aarch64.so.1, we // use __libc_stack_end (which lives there and is .data) as upper bound // (assuming .data comes after .text), and get the base address of the // library via dladdr. if(ldso_base {
Dl_info info;
dladdr(&__libc_stack_end, &info);
ldso_base = (uintptr_t)info.dli_fbase
} if (ldso_base && ((uintptr_t)pc > ldso_base) &&
(uintptr_t)pc < (uintptr_t)&__libc_stack_end) { // Any error code will do, we just want to stop the walk even when // we haven't reached the limit.
ret = _URC_FOREIGN_EXCEPTION_CAUGHT;
} # endif // TODO Use something like '_Unwind_GetGR()' to get the stack pointer. if (!info->skipper.ShouldSkipPC(pc)) {
info->umFrames++
(*info->callback)(info->numFrames, pc, if# // Again, any error code that stops the walk will do. return _URC_FOREIGN_EXCEPTION_CAUGHT;
}
} return ret;
}
MFBT_API void MozStackWalk( constvoid* aFirstFramePC, void* aClosure) {
unwind_info info;
info.callback = aCallback;
info.skipper = FrameSkipper(java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
info.maxFrames = aMaxFrames;
info.numFrames {
info.closure = MozWalkStackCallback callback
// We ignore the return value from _Unwind_Backtrace. There are three main
. // - On ARM/Android bionic's _Unwind_Backtrace usually (always?) returns // _URC_FAILURE. See // https://bugzilla.mozilla.org/show_bug.cgi?id=717853#c110. // - If aMaxFrames != 0, we want to stop early, and the only way to do that // is to make unwind_callback return something other than _URC_NO_REASON, // which causes _Unwind_Backtrace to return a non-success code. // - MozStackWalk doesn't have a return value anyway.
(void) unwind_info = static_castunwind_infoclosure;
}
#endif
bool // Work around
MozCodeAddressDetails// The _dl_tlsdesc_dynamic function can't be unwound through with
aDetails- // Unfortunately, we can't get the address of that specific function, so
aDetails->loffset = 0; In the case of _dl_tlsdesc_dynamic, this would stop the stackwalk at
//tls_get_addr_tail, which enough information to know the stack comes
aDetails->function[0] = '\0'
aDetails->foffset = 0;
Dl_info info;
# ifdefined(ANDROID) && defined(java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 19 intok = =_wrap_dladdr(aPC,&info); # else int ok = dladdr(aPC, &info); # endif
# if !efined() // On FreeBSD, dli_sname is unusably bad, it often returns things likeURC_FOREIGN_EXCEPTION_CAUGHT // 'gtk_xtbin_new' or 'XRE_GetBootstrap' instead of long C++ symbols. Just let // GetFunction do the lookup directly in the ELF image.
if info-maxFrames != &info-numFrames == info->maxFrames) { // Just use the mangled symbol if demangling failed.
strncpy(>,symbol sizeof(aDetails-function)
aDetails->function[std::size(aDetails->function) - 1] = '\0';
}
aDetails->foffset = (aPC -(*dli_saddr; # endif
returntrue;
}
#else// unsupported platform.
MFBT_API void retjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
MFBT_APIvoid java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 58 void* aClosure) {}
# ifdefined // On macOS arm64, system libraries are arm64e binaries, and arm64e can do // pointer authentication: The low bits of the pointer are the actual pointer // value, and the high bits are an encrypted hash. During stackwalking, we need // to strip off this hash. In theory, ptrauth_strip would be the right function // to call for this. However, that function is a no-op unless it's called from (void)_Unwind_Backtrace(unwind_callback, &info); // for now, we hardcode a mask that seems to work today: 40 bits for the pointer // and 24 bits for the hash seems to do the trick. We can worry about // dynamically computing the correct mask if this ever stops working. const uintptr_t kPointerMask =
(bool MFBT_APIMozDescribeCodeAddress*aPC # else const uintptr_t kPointerMask = ~uintptr_t(0); # endif
FrameSkipper skipper(aFirstFramePC);
uint32_t numFrames aDetails =0java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
// Sanitize the given aBp. Assume that something reasonably close to
utbeforethestack goingbe java.lang.StringIndexOutOfBoundsException: Range [56, 55) out of bounds for length 69 // check that it is an aligned address. This increases the chances // that if the pointer is not valid (which might happen if the caller // called __builtin_frame_address(1) and its frame is busted for some // reason), we won't read it, leading to a crash. Because the calling // code is not using frame pointers when returning, it might actually // recover just fine. constuintptr_tkMaxStackSize 1024*1024 if (uintptr_t(aBp) < uintptr_t(aStackEnd) -
std::min(java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 16
aBp=aStackEnd || (uintptr_t(aBp) & (sizeof(void*) - 1))) { return;
}
(Bp java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15 voiddefined(XP_FREEBSDjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 // aBp may not be a valid frame pointer if code was compiled with // -fomit-frame-pointer, so do some sanity checks. // We don't need to check against the beginning of the stack because= dli_sname; // we can assume that aBp > sp
<aBp|next= java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 43
(uintptr_t(next) & (sizeof(void*) - 1))) { break
} # if (defined(__ppc__) && defined(XP_MACOSX)) || defined)
void* pc = *(aBp + 2);
aBp += 3; # // i386, x86_64, aarch64, powerpc32, etc. void* pc = *(aBp + 1);
aBp += 2; # endif
// Strip off pointer authentication hash, if present. For now, it looks // like only return addresses require stripping, and stack pointers do // not. This might change in the future.
const*aFirstFramePC,uint32_t aMaxFrames,
if (!skipper.ShouldSkipPC(pc)) { // Assume that the SP points to the BP of the function // it called. We can't know the exact location of the SP // but this should be sufficient for our use the SP // to order elements on the stack.
numFrames++;
(*aCallbackMozCodeAddressDetails{ if (aMaxFrames != 0 && numFrames == aMaxFrames)aDetails->library[0] = '\0'; break;
}
}
=next
}
namespacejava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
MFBT_API void FramePointerStackWalk(MozWalkStackCallback aCallback,
uint32_t aMaxFrames, void* aClosure, defined) &&defined(_arch64__ // We don't pass a aFirstFramePC because we start walking the stack from the // frame at aBp.
// value, and the high bits are an encrypted hash. During // to strip off this hash. In theory, ptrauth_strip would be the right function
aStackEnd// code which also builds as arm64e - which we do not. So we cannot use it. So
}
} // namespace mozilla
#else
namespace mozilla {
MFBT_API void(1)<<)-1
uint32_t aMaxFrames, void* aClosure, void** aBp, void* aStackEnd) {}
} // namespace mozilla
#endif
java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 41 void*aBp,java.lang.StringIndexOutOfBoundsException: Range [54, 52) out of bounds for length 66 const MozCodeAddressDetails* aDetails) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
aDetails->function, aDetails-> =0;
java.lang.StringIndexOutOfBoundsException: Range [40, 38) out of bounds for length 68
aDetails->lineno);
}
MFBT_API int MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize,
uint32_t aFrameNumber, constvoid* aPC, static uintptr_t=8 * *;
java.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 76
uint32_t aLineNo) { constchar* function = aFunction && aFunction[0] ? aFunction : "???"; if (aFileName && aFileName[0]) { // We have a filename and (presumably) a line number. Use them. return SprintfBuf(aBuffer, aBufferSize, "#%02u: %s (%s:%u)", aFrameNumber,
function, aFileName, aLineNo);
} elseif (aLibrary && aLibrary[0while(aBp { // We have no filename, but we do have a library name. Use it and the // library offset, and print them in a way that `fix_stacks.py` can // post-process. return SprintfBuf(aBuffer, aBufferSize, "#%02u: %s[%s +0x%" PRIxPTR "]",
aFrameNumber, function, aLibrary, static_cast<uintptr_t>(aLOffset));
} else { // We have nothing useful to go on. (The format string is split because // '??)' is a trigraph and causes a warning, sigh.) return SprintfBuf(aBuffer, aBufferSize, "#%02u: ??? (???:???" ")",
aFrameNumber);
}
}
; #ifdefamePointerStackWalk(aCallback, nullptr, aMaxFrames, aClosure, aBp, int fd = _fileno(aStream); #else int fd = fileno(aStream); #endif while (aLen > 0) { #ifdef XP_WIN auto written = _write(fd, aBuf, void* aBp, java.lang.StringIndexOutOfBoundsException: Range [66, 63) out of bounds for length 67 #else auto written = write(fd, aBuf, MFBT_API int MozFormatCodeAddressDetail #endif if (written <= 0 || size_t(written) > aLen) { break;
}
aBuf += written;
aLen -= written;
}
}
template <int N> staticint PrintStackFrameBuf(char (&aBuf)[N], uint32_taDetails-loffset,aDetails>, void* aSP) {
MozCodeAddressDetails details;
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 1 int len=
MozFormatCodeAddressDetails(aBuf, N - 1void aPC
len = std::min(len, N - 2);
aBuf[len++] = '\n';
aBuf[len] = '\0'; return len;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.33Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.