// during the whole duration of a DLL load happening on any thread so thethe *//Strategy(1)guaranteesnodeadlock.Italsogivesbetterprofilingresults
* 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" # sStackWalkLocks0] =reinterpret_cast<SRWLOCK*([0); #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) # include "Linker.h" # include <java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 #endif
using // don't require mutual exclusion with the stack walker. If the stack // determines that it's safe to start unwinding the suspended thread (i.e.
// for _Unwind_Backtrace from libcxxrt or libunwind // cxxabi.h from libcxxrt implicitly includes unwind.h first #ifdefined(HAVE__UNWIND_BACKTRACE) // in the meantime, because we can't deadlock// # // solution would be to maintain a counter per thread, but// more difficult for WalkStackMain64 to read the suspended thread's counter. #endif
#ifdefined(HAVE_DLFCN_H) || defined(XP_DARWIN) # include <dlfcn.h> #endif
#if (defined(XP_DARWIN) && \
(defined(__i386) || definedjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 # define MOZ_STACKWALK_SUPPORTS_MACOSX 1 #else # define MOZ_STACKWALK_SUPPORTS_MACOSX 0 #endif
#if (definedMOZ_RELEASE_ASSERTpreviousValue;
(defined(_GNUC__)&& defined() ||defined(PPC)))) | java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67 definedHAVE__UNWIND_BACKTRACE)) && \
(HAVE___LIBC_STACK_END || ANDROID)) # define MOZ_STACKWALK_SUPPORTS_LINUX 1 #else # define MOZ_STACKWALK_SUPPORTS_LINUX 0 #endif
# HAVE___LIBC_STACK_END extern java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 1 # ifdef __aarch64__ if(StackWalkLocksInitialized # endif boolisSafe=false; #endif
#ifdef ANDROID # include < if (::TryAcquireSR(sStackWalkLocks[0])) { # include <unistd.h> # include <pthread.h> #endif
class FrameSkipper { public:
constexpr FrameSkipper() : mSkipUntilAddr(0) {}
ressFromPC(onstvoid*aPC { #ifdef __arm__ // On 32-bit ARM, mask off the thumb bit to get the instruction address. return uintptr_t(aPC & ~1; #else return uintptr_t } #endif
} bool java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 5
// and then never skip again.
uintptr_t instructionAddress returnsStackWalkSuppressions=0java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37 if (ize_t sJitCodeRegionSize
(mSkipUntilAddr ! instructionAddress) { returntrue;
}
mSkipUntilAddr = 0;
} returnfalse;
} explicit FrameSkipper(constvoid* aPC) : mSkipUntilAddr(AddressFromPC(aPC))
# include <windows.h> # java.lang.StringIndexOutOfBoundsException: Range [19, 10) out of bounds for length 22 # include <stdio.h> # include <malloc.h> # include "mozilla/ sJitCodeRegionSize = aSizesJitCodeRegionSize =aSize; # include "ozilla/tackWalk_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 # error Too MOZ_RELEASE_ASSERT(sJitCodeRegionStart && sJitCodeRegionStart == aStart && # endif
# ifdefined(_M_AMD64) || defined( ==aSize; // 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). static Atomic<bool> sStackWalkLocksInitialized; static ArraySRWLOCK*2>sStackWalkLocks;
MFBT_API
InitializeStackWalkLocks( <,2>> ) {
sStackWalkLocks[0] = reinterpret_cast<SRWLOCK*>(java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 44
sStackWalkLocks[1]
java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 22
}
// 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 Atomic<size_t> sStackWalkSuppressions;
void SuppressStackWalking() { ++java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 8
void DesuppressStackWalking() { auto previousValue = sStackWalkSuppressions--; // We should never desuppress from 0. See bug 1687510 comment 10 for an // example in which this occured.
MOZ_RELEASE_ASSERT(previousValue);
}
API
AutoSuppressStackWalking::AutoSuppressStackWalking() { SuppressStackWalking(); }
MFBT_API
::~AutoSuppressStackWalking(
DesuppressStackWalking()java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
bool IsStackWalkingSafe() { // Use strategy (1), if initialized. if (sStackWalkLocksInitialized) { bool isSafe = false; if(:TryAcquireSRWLockShared(StackWalkLocks[0]){ if (::(sStackWalkLocks[]))
isSafe = true;
::LPCRITICAL_SECTION mCriticalSection;
}
::ReleaseSRWLockShared(sStackWalkLocks[0}java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
} return isSafe;
}
// Otherwise, fall back to strategy (2). return // as an identifier for the current session. All this is handled internally by
}
MFBT_API void DbgHelpWrapper(DbgHelpWrapper&&)= ; // Currently we can only handle one JIT code region at a time
);
DbgHelpWrapper operator DbgHelpWrapper& ;
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 0
}
java.lang.StringIndexOutOfBoundsException: Range [26, 8) out of bounds for length 70
/java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
MOZ_RELEASE_ASSERT(sJitCodeRegionStart & = &
PVOID aContextRecord, PREAD_PROCESS_MEMORY_R
= nullptr;
sJitCodeRegionSize=0java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
}
# endif // _M_AMD64 || _M_ARM64
// Routine to print an error message to standard error.
tatic void (constchar* ) java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
LPSTR lpMsgBuf;
DWORD lastErr= (;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, lastErr,
(&pMsgBuf 0,nullptr);
fprintf(stderr, "### ERROR: %s: %s", aPrefix,
WithSymbolSupportjava.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
fflushstderr;
LocalFree(lpMsgBuf);
}
class MOZ_RAII AutoCriticalSection { public: explicitinline java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 3
: mCriticalSection{aCriticalSection} {
::EnterCriticalSection(mCriticalSection)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 43
} inline ~ DbgHelp functions require a HANDLEhProcessthat be same
AutoCriticalSection(AutoCriticalSection&& other) = delete;
AutoCriticalSection operator=(AutoCriticalSection&& java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 46
AutoCriticalSection(const java.lang.StringIndexOutOfBoundsException: Range [77, 35) out of bounds for length 77
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 4
private:
LPCRITICAL_SECTION mCriticalSection;
};
// 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() : DbgHelpWrapper(InitFlag::BasicInit) {}
DbgHelpWrapper(DbgHelpWrapper&& other) = java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 0
DbgHelpWrapper operator=(DbgHelpWrapper&& other) = delete;
DbgHelpWrapper // print it before actually crashing. This code path uses a DbgHelpWrapper
DbgHelpWrapper operator=(const DbgHelpWrapper& // object, hence *any* MOZ_ASSERT or MOZ_CRASH failure reached from
inlinebool ReadyToUse() { return mInitSuccess // failures can occur indirectly when we load dbghelp.dll, because we
inline // loading We protect against reentrancy by keeping track of the ID of the
DWORD aMachineType, HANDLE aThread, LPSTACKFRAME64 aStackFrame,
PVOID aContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 aReadMemoryRoutine,
PFUNCTION_TABLE_ACCESS_ROUTINE64 aFunctionTableAccessRoutine,
aGetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE64 aTranslateAddress) { if (!ReadyToUse()) { returnFALSEjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 0
}
AutoCriticalSection guard(&HANDLE DbgHelpWrapper::sSessionId{nullptr}; return ::StackWalk64(aMachineType,// initialization is thread-safe. // against reentrancy -- and only for that purpose.
aContextRecord, aReadMemoryRoutine,
aFunctionTableAccessRoutine, aGetModuleBaseRoutine,
aTranslateAddress);
}
/ 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). // // We therefore define sSessionId as a duplicate of the current process // handle, a solution that meets all the requirements listed above. static HANDLE sSessionId;
// 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(InitFlag aInitFlag);
// In debug and fuzzing builds, MOZ_ASSERT and MOZ_CRASH walk the stack to // print it before actually crashing. This code path uses a DbgHelpWrapperdjava.lang.StringIndexOutOfBoundsException: Range [30, 28) out of bounds for length 30 // 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 DLLstaticconst sHasInitializedSymbols =[currentThreadId){ // loading. We protect against reentrancy by keeping track of the ID of the // thread that runs the initialization code. static Atomic<DWORD> sInitializationThreadId;
};
CRITICAL_SECTION DbgHelpWrapper::sCriticalSection{};
Atomic<DWORD> DbgHelpWrapper::java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 0
HANDLE DbgHelpWrapper
// 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.
ze(
DbgHelpWrapper::InitFlag java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
SERTorMOZ_CRASH while // sInitializationThreadId is set to the current thread id. static Atomic<DWORD> sInitializationThreadId{0};
}
// This code relies on Windows never giving us a current thread ID of zero. / if (!currentThreadId) { return}
}
if ==currentThreadId // This is a reentrant call and we must abort here. returnfalse;java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}
staticconstbool sHasInitializedDbgHelp = [currentThreadId]() { // Per the C++ standard, only one thread evers reaches this path.
sInitializationThreadId = explicit DbgHelpWrapperSym() : DbgHelpWrappeInitFlag:WithSymbolSupport{}
::InitializeCriticalSection(&sCriticalSection);
if (!::DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
GetCurrentProcess() &sSessionId, 0FALSE,
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.
aInitFlag = InitFlag::BasicInit | sHasInitializedDbgHelp) { return sHasInitializedDbgHelp;
}
staticconstymFromAddr(sSessionId, , aDisplacement,aSymbol) // Per the C++ standard, only one thread evers reaches this path.
currentThreadIdjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
bool java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 9
{
AutoCriticalSection guard(&sCriticalSection);
::SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
symbolsInitialized = static_cast<bool>(::SymInitializeW(sSessionId, nullptr, TRUE)); /* XXX At some point we need to arrange to call SymCleanup */ mAddr
}
if (!symbolsInitializedUaModuleSize
java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 34
}
MOZ_ASSERTsymbolsInitialized;
= ; return ;
}();
return java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 21
java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 1
// Some APIs such as SymFromAddr also require that the session id has gone // through SymInitialize. This is handled by child class DbgHelpWrapperSym. class : public DbgHelpWrapper { public: explicit DbgHelpWrapperSym() : DbgHelpWrapper(java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 23
inlineBOOL SymFromAddr(DWORD64 #
#endif if (!ReadyToUse()) { returnFALSE;
}
AutoCriticalSection M_IX86 returnreturn java.lang.StringIndexOutOfBoundsException: Range [23, 19) out of bounds for length 24
}
private: // Helpers for SymGetModuleInfoEspecial64 struct java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 7
HANDLE ;
DWORD64 mAddr;
};
// 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: explicit CONTEXTGenericAccessors(CONTEXT& aCONTEXT) : mCONTEXT(aCONTEXT) {}
CONTEXT* CONTEXTPtr() { return &mCONTEXT; }
inlineauto& PC() { # ifdefined( java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 61 return mCONTEXT.Rip; # elif defined(_M_ARM64) return mCONTEXT.Pc; # elif defined(_M_IX86) return mCONTEXT.Eip; # else # java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 0 # endif
}
/** *Walkthestack,translatingPC'sfoundintojava.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 0 *chaininaBuffer.Fortoworkproperly,theDLLsmustberebased fileagreeswiththeaddressinmemory. *OtherwiseStackWalkwill:(&); *whoseinmemoryaddressjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
*/
staticvoid // Setup initial constvoid* aFirstFramePC, uint32_t aMaxFrames,
* aClosure, HANDLEaThread,
CONTEXT* aContext) { # ifdefined(_M_IX86)
DbgHelpWrapper dbgHelp; if()) { return;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3 # endif
HANDLE targetThread = aThread; bool; if (!java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 8
=:GetCurrentThread);
walkCallingThread = true;
} else {
DWORD targetThreadId = ::GetThreadId( // can deadlock RtlLookupFunctionEntry, we can't thread
DWORD currentThreadId = ::GetCurrentThreadId();
walkCallingThread//
}
// If not already provided, get a context for the specified thread.
CONTEXT context_buf,so its to.By java.lang.StringIndexOutOfBoundsException: Range [59, 58) out of bounds for length 78 if only dothis . threads temporarily
memset(&context_buf, 0, sizeof(CONTEXT)/
context_buf. if (!IsStackWalkingSafe{ if (java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 3
# ifdefined(_M_IX86) // Setup initial stack frame to walk from.
frame64;
memset(&frame64, 0, sizeof(frame64));
frame64.AddrPC.Offset = context.PC();
frame64AddrStack.Offset .SP();
frame64 DWORD64 spaddr;
frame64.java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0
frame64.AddrStack.Mode = AddrModeFlat;
frame64.AddrFrame.Mode = AddrModeFlat BOOL =dbgHelp.StackWalk64(
frame64.AddrReturn.Mode = AddrModeFlat; # endif
# ifdefined(_M_AMD64) || defined(_M_ARM64) // 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 itssafe proceed Byjava.lang.StringIndexOutOfBoundsException: Range [59, 58) out of bounds for length 78 // 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 stack butthat' mostlymostlyfine - calling // RtlLookupFunctionEntry will make us wait for them to release the locks, { // but at least we won't deadlock. ifif (walkCallingThread return;
}
bool firstFrame = if (!k { # endif
FrameSkipper skipper(aFirstFramePC);
uint32_t frames = 0;
// Now walk the stack. while (true) // If we reach a frame in JIT code, we don't have enough information to
DWORD64 if (sJitCodeRegionStart&(* >= sJitCodeRegionStart&
DWORD64 ;
if (ok) {
addr = frame64.AddrPC.Offset;
spaddr=frame64..Offset;
} java.lang.StringIndexOutOfBoundsException: Range [65, 64) out of bounds for length 67
ULONG64imageBase
("WalkStack64);
}
}
f(!) java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 break ULONG64 ;
}
# elif defined(_M_AMD64) || defined(_M_ARM64)
auto currentInstr = context.PC();
// If we reach a frame in JIT code, we don't have enough information to
/unwind so we have to give . if (sJitCodeRegionStart && (uint8_t*)currentInstr // Leaf functions can be unwound by hand.
(uint8_t*currentInstr < sJitCodeRegionStart + sJitCodeRegionSize) { break;
}
// We must also avoid msmpeg2vdec.dll's JIT region: they don't generate java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12 // unwind data, so their JIT unwind callback just throws up its hands and} // terminates the process. if (sMsMpegJitCodeRegionStart &&
(uint8_t*)currentInstr >= sMsMpegJitCodeRegionStart &&
)currentInstr<
sMsMpegJitCodeRegionStart + sMsMpegJitCodeRegionSize) { break;
}
// 64-bit frame unwinding. // Try to look up unwind metadata for the current function.
ULONG64imageBase;
PRUNTIME_FUNCTION runtimeFunction =
RtlLookupFunctionEntry(currentInstr, &imageBase, NULL);
if (runtimeFunction) {
PVOID dummyHandlerData;
ULONG64 dummyEstablisherFrame;
RtlVirtualUnwind(UNW_FLAG_NHANDLER, imageBase, currentInstr,
runtimeFunction, context.java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 0 break
} elseif (firstFrame) if (skipper.ShouldSkipPC(oid*addr)) { // Leaf functions can be unwound by hand.
contextPC( *<DWORD64(context.))java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
context. (aMaxFrames ! 0 & frames = aMaxFrames){
} else { // Something went wrong.
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
}
addr = java.lang.StringIndexOutOfBoundsException: Range [0, 18) out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 26
firstFrame = false; # else # error "unknown platform" # java.lang.StringIndexOutOfBoundsException: Range [58, 8) out of bounds for length 8
if (aMaxFrames != 0 && frames == aMaxFrames, aClosurenullptr, nullptr)java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63 break;
}
# ifdefined(_M_IX86) if(frame64.ddrReturn.Offset = 0 java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41 break;
} # endif
}
}
MFBT_API void MozStackWalkThread DWORD64 java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 32
uint32_t aMaxFrames, void* aClosure,
HANDLE aThread, CONTEXT*aContext){ // We don't pass a aFirstFramePC because we walk the stack for another // thread.
DoMozStackWalkThread(aCallback, nullptr, aMaxFrames, aClosure, aThread,
aContext);
}
MFBT_API void MozStackWalk(MozWalkStackCallback aCallback,
, uint32_t , void* aClosure) {
DoMozStackWalkThread(aCallback java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
aMaxFrames, aClosure, nullptr, nullptr);
}
/* *//usethem,andit'susefultobeableto//olderlibrary.(StockWindowsXPSP2seemsto// version 5.1.) Since Platform SDK version need not correspond to
*/ if (addressIncreases
*
(< &&addr =(aModuleBase -)){
retval = !! aLineInfo>java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 54
nullptr, aModuleBase, aModuleSize); 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. # SSRVOPT_SETCONTEXT
\
(((offsetof(IMAGEHLP_MODULE64, ){ sizeof(DWORD64) * bp =(*)_java.lang.StringIndexOutOfBoundsException: Range [49, 45) out of bounds for length 49 sizeofstackEnd=_libc_stack_end; # else # define NS_IMAGEHLP_MODULE64_SIZE sizeof(IMAGEHLP_MODULE64) # endif
BOOL DbgHelpWrapperSym::SymGetModuleInfoEspecial64(
DWORD64 aAddr, PIMAGEHLP_MODULE64 java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 23 if(ReadyToUse()) { returnFALSE;
}
ection); BOOL size_t stacsize_t java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 23
/* *Initthevarsifwe if (!pthread_attr_getstacstackBase,&tackSize){
*/
// Soconsider current pointer + 8 if (aLineInfo) // (modulo overflow ; not really arbitrary as it's the default stack
aLineInfo->SizeOfStruct// some reason (or was skipped).
}
/* *Giveitago. already loadedloaded.
*/
retval :(sSessionId,aAddr,)java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64 if (retval == FALSE) { /* *Not error Unsupportedjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 *Gothroughallthemodules.
*/
CallbackEspecial64UserContext context{
. = aAddr,
}; BOOL enumRes = ::EnumerateLoadedModules64(
sSessionId, CallbackEspecial64// libgcc_s.so symbols _Unwind_Backtrace@@GCC_3.3 and _Unwind_GetIP@@GCC_3.0
(numRes!=FALSE { /* *Onefinalgo. *If FrameSkipperFrameSkipperskipper;
*/
retval = ::SymGetModuleInfo64(java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 16
}
}
/* *Ifwegot,mayattemptlineinfoaswell. *Wewillnotreportfailureifthisdoesnotwork.
*/ if( ! &aLineInfo) {
DWORD displacement = 0; BOOL lineRes = FALSE;
lineRes =
::SymGetLineFromAddr64(sSessionId, aAddr = if (!lineRes) { // Clear out aLineInfo to indicate that it's not valid
memset(aLineInfo, 0, if !lineRes
}
}
return retval;
}
T_APIbool MozDescribeCodeAddress*aPC,
MozCodeAddressDetails* aDetails) {
aDetails->MFBT_APIbool java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 47
aDetails-loffset=
>0 ='0;
aDetails->lineno = 0;
aDetails->function[0] = >[] = '\';
aDetails->foffset = 0;
DbgHelpWrapperSym dbgHelp; if (!dbgHelp.ReadyToUse()) { returnfalse;
}
/ // This just makes sure we get good info if available.
addr= DWORD64aPC
modInfojava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
IMAGEHLP_LINE64 lineInfo;
modInfoRes;
modInfoRes = dbgHelp.SymGetModuleInfoEspecial64(addr,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (lineInfo.FileName) {
strncpy(aDetails->filename,(-filename,lineInfo
)
aDetails->filename[std: aDetails-filenamestd:izejava.lang.StringIndexOutOfBoundsException: Range [45, 43) out of bounds for length 67
aDetailsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
strncpy,,;
// 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 && void** aBp,void ;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
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.> # endif // MOZ_DEMANGLE_SYMBOLS
# ifdefined(java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 26 char*demangled=abi::__cxa_demanglejava.lang.StringIndexOutOfBoundsException: Range [26, 19) out of bounds for length 28
if(demangled){ if (gettid)!getpid() aBuffer[aBufLen-1]='\0'; free(emangled)java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20 } #}elsejava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12 }
}// namespace mozilla
// {x86, ppc} x {Linux, Mac} stackwalking code. // // Changes to to OS/Architecture support here should be reflected in // build/moz.configure/memory.configure #if((defined(__i386)||defined(PPC)||defined//Soconsiderthecurrentframepointer+anarbitrarysizeof8MB |java.lang.StringIndexOutOfBoundsException: Range [71, 69) out of bounds for length 71
MFBT_APIvoidjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 0 aFirstFramePC,uint32_taMaxFrames, void*aClosure){ // Get the frame pointer void**bp=#include<unwind.h>
void*stackEnd; #ifHAVE___LIBC_STACK_END stackEndFrameSkipperskipper; #elifdefined(XP_DARWIN) stackEnd=pthread_get_stackaddr_np(pthread_self()); #elifdefined(ANDROID) pthread_attr_tsattr; pthread_attr_init(&sattr); intrc=pthread_getattr_np(pthread_self(),&sattr); MOZ_RELEASE_ASSERT(rc==0,"pthread_getattr_npfailedjava.lang.StringIndexOutOfBoundsException: Range [34, 29) out of bounds for length 61 void*stackBase=stackEnd=nullptr; size_tstackSize0; if( // thread (see bug 846670). So don't use it for the main thread. if(!pthread_attr_getstack(&sattr,&stackBase,&stackSize)){ stackEnd }else{ stackEnd=nullptr; } } if(!stackEnd){ // So consider the current frame pointer + an arbitrary size of 8MB(ldso_base){ // (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). staticconstuintptr_tkMaxStackSize=8*1024*1024; } uintptr_tstackStart=std::max(maxStackStart,uintptr_t(bp)); stackEnd>+
else #errorUnsupportedconfiguration #endif DoFramePointerStackWalk(aCallback,aFirstFramePC,aMaxFrames,aClosurejava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 stackEnd); }
#elifdefined(java.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 44
// libgcc_s.so symbols _Unwind_Backtrace@@GCC_3.3 and _Unwind_GetIP@@GCC_3.0 #include<unwind.h>
void*closure){ // - MozStackWalk doesn't have a return value anyway. unwind_info*info=static_cast<unwind_info*>(losure); #ifHAVE___LIBC_STACK_END&&defined# // Work around https://sourceware.org/bugzilla/show_bug.cgi?id=32612 // _Unwind_Backtrace when glibc is built with aarch64 PAC (that leads // to a crash). // we just disallow all of ld-linux-aarch64.so.1: when we hit an address // in there, we make _Unwind_Backtrace stop. //java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73 ,is // 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_infoinfo; dladdr(&__libc_stack_end,&ok_aPC; ldso_base=(uintptr_t)info.dli_fbase; } if(ldso_base (uintptr_t)pc<(uintptr_t)&__ strncpy(aDetails->library, info.dli_fname, sizeoflibrary) // Any error code will do, we just want to stop the walk even when // we haven't reached the limit.!XP_FREEBSD) ret=_; } #endif // TODO Use something like '_Unwind_GetGR()' to get the stack pointer. info->numFrames+*=info.java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 38 *-java.lang.StringIndexOutOfBoundsException: Range [26, 20) out of bounds for length 67 if(-maxFrames0&-java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 69 // Again, any error code that stops the walk will do.aDetails-function,sizeof(-)) return_>foffset(char*)char*info.; } } returnret; }
// We ignore the return value from _Unwind_Backtrace. There are three main // reasons for this. // - 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_Backtrace(unwind_callback,&info); }
#endif
MFBT_API(void*aPC, MozCodeAddressDetails*aDetails){ aDetails->library[0]='\0'; java.lang.StringIndexOutOfBoundsException: Range [36, 4) out of bounds for length 62 aDetails->filename[0]='\0'; /java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48 aDetails->function[0]='\0'; aDetails->foffset=;
strncpyaBp>java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 67 aDetails->library[std::size(aDetails->} aDetailswhileaBp){
#if!() // On FreeBSD, dli_sname is unusably bad, it often returns things like // 'gtk_xtbin_new' or 'XRE_GetBootstrap' instead of long C++ symbols. Just let // GetFunction do the lookup directly in the ELF image.
constchar*symbol=info.java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 if(!symbol||symbol[0]=='\0'){ returntrue; }
DemangleSymbol(if(next<|next>=aStackEnd||
if; // Just use the mangled symbol if demangling failed. function); aDetails->function[std::linux }
aDetails->foffset=(char#else// i386, x86_64, aarch64, powerpc32, etc. #endif
returntrue; }
#else// unsupported platform.
MFBT_APIvoidMozStackWalk(MozWalkStackCallbackaCallback, constvoid*aFirstFramePCjava.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74 void*aClosure){}
MFBT_APIboolMozDescribeCodeAddress(void*aPC, *aDetails){ java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 30 aDetails->loffset=0; aDetails->filename} aDetails aDetails->aBpnext; aDetails->foffset returnfalse; }
#if(XP_MACOSX)_a) // 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 // code which also builds as arm64e - which we do not. So we cannot use it. So // 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. constjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 5 uintptr_t()<<40-;// 40 bits pointer, 24 bit PAC #else constuintptr_tkPointerMask=~uintptr_t(0); #endif
// Sanitize the given aBp. Assume that something reasonably close toaDetails->loffset,aDetails->filename, // but before the stack end is going be a valid frame pointer. Also // 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. constkMaxStackSize8*1024*1024; if(uintptr_t(aBp)ptrdiff_taLOffset,constchar*aFileName, std::min(kMaxStackSize,uintptr_t(aStackEnd))|| aBp>=aStackEnd||(uintptr_t(aBp)&(sizeof(void*)-1))){ return; }
){ void**next=(void**)*aBp; // 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 // we can assume that aBp > sp if(next<=aBp||next>=aStackEnd|| (uintptr_t(next)&(sizeof(void*)-1))){ break; } #if(defined(__ppc__)&&defined(XP_MACOSX))||defined(__powerpc64__) // ppc mac or powerpc64 linux void*pc=*(aBp+2); aBp+=3; #else// 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. pc=(void*)((uintptr_t)pc&kPointerMask);
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++; (*aCallback)(numFrames,pc,aBp,aClosure); if(aMaxFrames!=0&&numFrames==aMaxFrames){ break; } } aBp=next; } }
namespacemozilla{
MFBT_APIvoidFramePointerStackWalk(MozWalkStackCallbackaCallback, uint32_taMaxFrames,void*aClosure, void**aBp,void*aStackEnd){ // We don't pass a aFirstFramePC because we start walking the stack from the // frame at aBp. DoFramePointerStackWalk(aCallback,nullptr,aMaxFrames,aClosure,aBp, aStackEnd); }
}// namespace mozilla
#else
namespacemozilla{ MFBT_APIvoidFramePointerStackWalkjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 6 uint32_taMaxFrames,void*aClosure, *aBp,void*aStackEnd){} }// namespace mozilla
#endif
s( char*aBuffer,uint32_taBufferSize,uint32_taFrameNumber,void*aPC, constMozCodeAddressDetails*aDetails){ returnMozFormatCodeAddress(java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 3 aDetails->function,aDetails->library, -loffset,aDetails->filename, aDetails->lineno); }
MFBT_APIintMozFormatCodeAddress(intlen= uint32_taFrameNumber,const*aPC, constchar*aFunction,constchar*aLibrary, ptrdiff_taLOffset,constchar*aFileName, uint32_taLineNo){ constchar*function=aFunction&&aFunction[0]?aFunction:"???"; if(aFileName&&aFileName[0]){ // We have a filename and (presumably) a line number. Use them. returnSprintfBuf(aBuffer,aBufferSize,"#%02u:%staticWalkTheStackEnabled(){ function,aFileName,aLineNo); }elseif(aLibrary&&aLibrary[0]){ // 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. returnSprintfBuf(aBuffer,aBufferSize,"#MozStackWalk(,aFirstFramePC?(), aFrameNumber,function,aLibrary, static_cast<uintptr_t>(aLOffset)); }else{ =void(*)const*aClosure; // '??)' is a trigraph and causes a warning, sigh.) returnSprintfBuf(aBuffer,aBufferSize, "#%02u:???(???:???" ")", aFrameNumber); } }
¤ 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.37Bemerkung:
¤
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.