diff --git a/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp b/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp index e7a2fb7b..0f84b864 100755 --- a/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp +++ b/engine/shared/library/sharedDebug/src/linux/DebugHelp.cpp @@ -682,11 +682,30 @@ bool DebugHelp::lookupAddress(uint64 address, char *libName, char *fileName, int // ---------------------------------------------------------------------- -void DebugHelp::getCallStack(uint32 *callStack, int sizeOfCallStack) +void DebugHelp::getCallStack(uint64 *callStack, int sizeOfCallStack) { + //-- backtrace() writes sizeOfCallStack void* entries. Handing it the + // caller's buffer directly only works when sizeof(void*) happens to + // equal the element size; under LP64 it wrote 8 bytes per entry into a + // 4-byte-per-entry array and overran the buffer by 2x. Capture into a + // native pointer array and widen instead, which is correct for both + // ILP32 and LP64. + enum { cs_maximumFrameCount = 256 }; + + if (sizeOfCallStack <= 0) + return; + for (int i = 0; i < sizeOfCallStack; ++i) callStack[i] = 0; - IGNORE_RETURN(backtrace(reinterpret_cast(callStack), sizeOfCallStack)); + + if (sizeOfCallStack > static_cast(cs_maximumFrameCount)) + sizeOfCallStack = static_cast(cs_maximumFrameCount); + + void *frames[cs_maximumFrameCount]; + int const frameCount = backtrace(frames, sizeOfCallStack); + + for (int i = 0; i < frameCount; ++i) + callStack[i] = reinterpret_cast(frames[i]); } // ====================================================================== diff --git a/engine/shared/library/sharedDebug/src/linux/DebugHelp.h b/engine/shared/library/sharedDebug/src/linux/DebugHelp.h index e297f8eb..973c07be 100755 --- a/engine/shared/library/sharedDebug/src/linux/DebugHelp.h +++ b/engine/shared/library/sharedDebug/src/linux/DebugHelp.h @@ -19,7 +19,10 @@ public: static void install(); static void remove(); - static void getCallStack(uint32 *callStack, int sizeOfCallStack); + //-- Entries are instruction addresses, so the buffer must be pointer-width + // capable. uint64 matches lookupAddress() below and is wide enough on + // both ILP32 and LP64. + static void getCallStack(uint64 *callStack, int sizeOfCallStack); static bool lookupAddress(uint64 address, char *libName, char *fileName, int fileNameLength, int &line); }; diff --git a/engine/shared/library/sharedDebug/src/shared/CallStack.cpp b/engine/shared/library/sharedDebug/src/shared/CallStack.cpp index 1df90532..2acb5ab9 100755 --- a/engine/shared/library/sharedDebug/src/shared/CallStack.cpp +++ b/engine/shared/library/sharedDebug/src/shared/CallStack.cpp @@ -59,9 +59,9 @@ void CallStack::debugPrint() const for (size_t i = 2; i < CALLSTACK_DEPTH; ++i) { if (DebugHelp::lookupAddress(m_callStack[i], libName, fileName, sizeof(fileName), line)) - DEBUG_REPORT_PRINT(true, (" (0x%08X) %s(%d) : caller %d\n", static_cast(m_callStack[i]), fileName, line, i - 1)); + DEBUG_REPORT_PRINT(true, (" (0x%016llX) %s(%d) : caller %d\n", static_cast(m_callStack[i]), fileName, line, i - 1)); else - DEBUG_REPORT_PRINT(true, (" unknown(0x%08X) : caller %d\n", static_cast(m_callStack[i]), i - 1)); + DEBUG_REPORT_PRINT(true, (" unknown(0x%016llX) : caller %d\n", static_cast(m_callStack[i]), i - 1)); } } @@ -76,9 +76,9 @@ void CallStack::debugLog() const for (size_t i = 2; i < CALLSTACK_DEPTH && m_callStack[i]!=0; ++i) { if (DebugHelp::lookupAddress(m_callStack[i], libName, fileName, sizeof(fileName), line)) - DEBUG_REPORT_LOG(true, (" (0x%08X) %s(%d) : caller %d\n", static_cast(m_callStack[i]), fileName, line, i - 1)); + DEBUG_REPORT_LOG(true, (" (0x%016llX) %s(%d) : caller %d\n", static_cast(m_callStack[i]), fileName, line, i - 1)); else - DEBUG_REPORT_LOG(true, (" unknown(0x%08X) : caller %d\n", static_cast(m_callStack[i]), i - 1)); + DEBUG_REPORT_LOG(true, (" unknown(0x%016llX) : caller %d\n", static_cast(m_callStack[i]), i - 1)); } } diff --git a/engine/shared/library/sharedDebug/src/shared/CallStack.h b/engine/shared/library/sharedDebug/src/shared/CallStack.h index 376f0ed3..120791d0 100755 --- a/engine/shared/library/sharedDebug/src/shared/CallStack.h +++ b/engine/shared/library/sharedDebug/src/shared/CallStack.h @@ -40,7 +40,8 @@ private: private: - uint32 m_callStack[S_callStack]; + //-- Instruction addresses; must be pointer-width capable (see DebugHelp::getCallStack). + uint64 m_callStack[S_callStack]; }; // ====================================================================== diff --git a/engine/shared/library/sharedDebug/src/shared/CallStackCollector.cpp b/engine/shared/library/sharedDebug/src/shared/CallStackCollector.cpp index 9e91cbb4..8162421a 100755 --- a/engine/shared/library/sharedDebug/src/shared/CallStackCollector.cpp +++ b/engine/shared/library/sharedDebug/src/shared/CallStackCollector.cpp @@ -49,7 +49,7 @@ namespace CallStackCollectorNamespace ~Node(); CrcString const & getName() const; - void addCallStack(uint32 * callStack); + void addCallStack(uint64 * callStack); void debugReport() const; @@ -63,7 +63,7 @@ namespace CallStackCollectorNamespace public: - uint32 * m_callStack; + uint64 * m_callStack; int m_calls; }; @@ -125,10 +125,10 @@ CrcString const & CallStackCollectorNamespace::Node::getName() const // ---------------------------------------------------------------------- -void CallStackCollectorNamespace::Node::addCallStack(uint32 * const callStack) +void CallStackCollectorNamespace::Node::addCallStack(uint64 * const callStack) { //-- Compute crc of memory - uint32 const crc = Crc::calculate(callStack, (sizeof(uint32) * CALLSTACK_DEPTH)); + uint32 const crc = Crc::calculate(callStack, (sizeof(*callStack) * CALLSTACK_DEPTH)); //-- Find callstack in list CallStackEntryMap::iterator iter = m_callStackEntryMap.find(crc); @@ -140,8 +140,8 @@ void CallStackCollectorNamespace::Node::addCallStack(uint32 * const callStack) else { //-- Create new callstack - uint32 * const newCallStack = new uint32[CALLSTACK_DEPTH]; - memcpy(newCallStack, callStack, sizeof(*newCallStack)); + uint64 * const newCallStack = new uint64[CALLSTACK_DEPTH]; + memcpy(newCallStack, callStack, sizeof(*newCallStack) * CALLSTACK_DEPTH); CallStackEntry callStackEntry; callStackEntry.m_callStack = newCallStack; @@ -180,7 +180,7 @@ void CallStackCollectorNamespace::Node::debugReport() const if (DebugHelp::lookupAddress(callStackEntry->m_callStack[j], libName, fileName, sizeof(fileName), line)) REPORT_LOG(true, (" %s(%d) : caller %d\n", fileName, line, j - 1)); else - REPORT_LOG(true, (" unknown(0x%08X) : caller %d\n", static_cast(callStackEntry->m_callStack[j]), j - 1)); + REPORT_LOG(true, (" unknown(0x%016llX) : caller %d\n", static_cast(callStackEntry->m_callStack[j]), j - 1)); } } } @@ -218,7 +218,7 @@ void CallStackCollector::sample(char const * const name) } //-- Sample the callstack - uint32 callStack[CALLSTACK_DEPTH]; + uint64 callStack[CALLSTACK_DEPTH]; DebugHelp::getCallStack(&callStack[0], CALLSTACK_DEPTH); //-- Add to the node diff --git a/engine/shared/library/sharedDebug/src/win32/DebugHelp.cpp b/engine/shared/library/sharedDebug/src/win32/DebugHelp.cpp index b80a6a45..a138d781 100755 --- a/engine/shared/library/sharedDebug/src/win32/DebugHelp.cpp +++ b/engine/shared/library/sharedDebug/src/win32/DebugHelp.cpp @@ -481,7 +481,7 @@ bool DebugHelp::loadSymbolsForDll(const char *name) // ---------------------------------------------------------------------- #pragma warning (disable: 4740 4748) -void DebugHelp::getCallStack(uint32 *callStack, int sizeOfCallStack) +void DebugHelp::getCallStack(uint64 *callStack, int sizeOfCallStack) { { for (int i = 0; i < sizeOfCallStack; ++i) @@ -525,7 +525,7 @@ void DebugHelp::getCallStack(uint32 *callStack, int sizeOfCallStack) if (stackWalk64(IMAGE_FILE_MACHINE_I386, process, process, &stackFrame, &context, NULL, functionTableAccess, getModuleBase, NULL)) { const DWORD64 Offset = stackFrame.AddrPC.Offset; - *callStack = DWORD(Offset); + *callStack = static_cast(Offset); } } } @@ -537,7 +537,7 @@ void DebugHelp::reportCallStack(int const maxStackDepth) // look up the call stack information int const callStackOffset = 2; int const callStackSize = callStackOffset + maxStackDepth; - uint32 * callStack = static_cast(_alloca((callStackOffset + maxStackDepth) * sizeof(uint32))); + uint64 * callStack = static_cast(_alloca((callStackOffset + maxStackDepth) * sizeof(uint64))); getCallStack(callStack, callStackOffset + maxStackDepth); // look up the caller's file and line @@ -553,7 +553,7 @@ void DebugHelp::reportCallStack(int const maxStackDepth) if (lookupAddress(callStack[i], lib, file, sizeof(file), line)) REPORT_LOG(true, ("\t%s(%d) : caller %d\n", file, line, i-callStackOffset)); else - REPORT_LOG(true, ("\tunknown(0x%08X) : caller %d\n", static_cast(callStack[i]), i-callStackOffset)); + REPORT_LOG(true, ("\tunknown(0x%016llX) : caller %d\n", static_cast(callStack[i]), i-callStackOffset)); } } } @@ -561,7 +561,7 @@ void DebugHelp::reportCallStack(int const maxStackDepth) // ---------------------------------------------------------------------- -bool DebugHelp::lookupAddress(uint32 address, char *libName, char *fileName, int fileNameLength, int &line) +bool DebugHelp::lookupAddress(uint64 address, char *libName, char *fileName, int fileNameLength, int &line) { UNREF(libName); diff --git a/engine/shared/library/sharedDebug/src/win32/DebugHelp.h b/engine/shared/library/sharedDebug/src/win32/DebugHelp.h index 74e379ab..bb7483bb 100755 --- a/engine/shared/library/sharedDebug/src/win32/DebugHelp.h +++ b/engine/shared/library/sharedDebug/src/win32/DebugHelp.h @@ -23,9 +23,9 @@ public: static bool loadSymbolsForDll(const char *name); - static void getCallStack(uint32 *callStack, int sizeOfCallStack); + static void getCallStack(uint64 *callStack, int sizeOfCallStack); static void reportCallStack(int const maxStackDepth = 4); - static bool lookupAddress(uint32 address, char *libName, char *fileName, int fileNameLength, int &line); + static bool lookupAddress(uint64 address, char *libName, char *fileName, int fileNameLength, int &line); static bool writeMiniDump(char const *miniDumpFileName=0, PEXCEPTION_POINTERS exceptionPointers=0); }; diff --git a/engine/shared/library/sharedFoundation/src/shared/Fatal.cpp b/engine/shared/library/sharedFoundation/src/shared/Fatal.cpp index c684c6e4..a82a7160 100755 --- a/engine/shared/library/sharedFoundation/src/shared/Fatal.cpp +++ b/engine/shared/library/sharedFoundation/src/shared/Fatal.cpp @@ -62,7 +62,7 @@ static void formatMessage(char *buffer, int bufferLength, int stackDepth, const // look up the call stack information const int callStackSize = callStackOffset + stackDepth; - uint32 callStack[callStackOffset + maxStackDepth]; + uint64 callStack[callStackOffset + maxStackDepth]; // allow complete disable of the call stack lookup if (stackDepth < 0) @@ -82,7 +82,7 @@ static void formatMessage(char *buffer, int bufferLength, int stackDepth, const if (ConfigSharedFoundation::getLookUpCallStackNames() && DebugHelp::lookupAddress(callStack[callStackOffset], lib, file, sizeof(file), line)) snprintf(buffer, bufferLength, "%s(%d) : %s %08x: \n", file, line, type, static_cast(Crc::calculate(format))); else - snprintf(buffer, bufferLength, "(0x%08X) : %s %08x: \n", static_cast(callStack[callStackOffset]), type, static_cast(Crc::calculate(format))); + snprintf(buffer, bufferLength, "(0x%016llX) : %s %08x: \n", static_cast(callStack[callStackOffset]), type, static_cast(Crc::calculate(format))); } else { @@ -126,7 +126,7 @@ static void formatMessage(char *buffer, int bufferLength, int stackDepth, const if (ConfigSharedFoundation::getLookUpCallStackNames() && DebugHelp::lookupAddress(callStack[i], lib, file, sizeof(file), line)) snprintf(buffer, bufferLength, " %s(%d) : caller %d\n", file, line, i-callStackOffset); else - snprintf(buffer, bufferLength, " (0x%08X) : caller %d\n", static_cast(callStack[i]), i-callStackOffset); + snprintf(buffer, bufferLength, " (0x%016llX) : caller %d\n", static_cast(callStack[i]), i-callStackOffset); const int length = strlen(buffer); buffer += length;