Merge pull request #34 from Galaxies-Reborn/x64-dx9-no-docker

Fix four LP64 defects and add Oracle 19 client discovery
This commit is contained in:
John
2026-07-26 12:45:03 -04:00
committed by GitHub
14 changed files with 102 additions and 55 deletions
+3 -2
View File
@@ -37,10 +37,11 @@ if(DEFINED ENV{ORACLE_HOME})
${ORACLE_HOME}/OCI/include) # Oracle XE on Windows
set(ORACLE_OCI_NAMES clntsh libclntsh oci)
set(ORACLE_NNZ_NAMES libnnz18 nnz18 libnnz21 nnz21 ociw32)
set(ORACLE_NNZ_NAMES libnnz18 nnz18 libnnz19 nnz19 libnnz21 nnz21 ociw32)
set(ORACLE_OCCI_NAMES libocci occi oraocci10 oraocci11)
set(ORACLE_LIB_DIR
${ORACLE_HOME}
${ORACLE_HOME}/lib
${ORACLE_HOME}/sdk/lib # Oracle SDK
${ORACLE_HOME}/sdk/lib/msvc
@@ -76,4 +77,4 @@ endif(DEFINED ENV{ORACLE_HOME})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Oracle DEFAULT_MSG ORACLE_LIBRARY ORACLE_INCLUDE_DIR)
mark_as_advanced(ORACLE_INCLUDE_DIR ORACLE_LIBRARY)
mark_as_advanced(ORACLE_INCLUDE_DIR ORACLE_LIBRARY)
@@ -781,16 +781,26 @@ void JavaLibrary::fatalHandler(int signum)
{
// try to see if our call stack came from C or Java
void *frameAddress = __builtin_frame_address(0);
// the address that generated the segfault is stored at an offset of 0x44 from
// the frame address
// @todo: find documentation on the offset to verify it is stable
void *crashAddress1 = *((void**)((static_cast<char *>(frameAddress)) + 0x44));
// pass the crash address to addr2line to get the file name where the crash occurred
// These are zero initialized because the strstr() checks below read them
// whenever a lookup fails.
static const int BUFLEN = 2048;
char lib1[BUFLEN], lib2[BUFLEN];
char file1[BUFLEN], file2[BUFLEN];
int line1, line2;
bool result1 = DebugHelp::lookupAddress(reinterpret_cast<uint64>(crashAddress1), lib1, file1, BUFLEN, line1);
char lib1[BUFLEN] = { '\0' }, lib2[BUFLEN] = { '\0' };
char file1[BUFLEN] = { '\0' }, file2[BUFLEN] = { '\0' };
int line1 = 0, line2 = 0;
bool result1 = false;
// The faulting address used to be read from a fixed 0x44 byte offset into
// this frame. That constant describes the 32-bit x86 frame layout only; on
// x86-64 it is both misaligned and meaningless, and dereferencing it from
// inside a SIGSEGV handler risks a recursive fault that loses the crash
// report entirely. The __builtin_return_address() probe below is portable
// and already covers this case.
#if defined(__i386__)
void *crashAddress1 = *((void**)((static_cast<char *>(frameAddress)) + 0x44));
result1 = DebugHelp::lookupAddress(reinterpret_cast<uint64>(crashAddress1), lib1, file1, BUFLEN, line1);
#endif
// do a second test based on the return address
// it turns out that in some java crashes we don't even have 2 return
@@ -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<void **>(callStack), sizeOfCallStack));
if (sizeOfCallStack > static_cast<int>(cs_maximumFrameCount))
sizeOfCallStack = static_cast<int>(cs_maximumFrameCount);
void *frames[cs_maximumFrameCount];
int const frameCount = backtrace(frames, sizeOfCallStack);
for (int i = 0; i < frameCount; ++i)
callStack[i] = reinterpret_cast<uint64>(frames[i]);
}
// ======================================================================
@@ -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);
};
@@ -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<int>(m_callStack[i]), fileName, line, i - 1));
DEBUG_REPORT_PRINT(true, (" (0x%016llX) %s(%d) : caller %d\n", static_cast<unsigned long long>(m_callStack[i]), fileName, line, i - 1));
else
DEBUG_REPORT_PRINT(true, (" unknown(0x%08X) : caller %d\n", static_cast<int>(m_callStack[i]), i - 1));
DEBUG_REPORT_PRINT(true, (" unknown(0x%016llX) : caller %d\n", static_cast<unsigned long long>(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<int>(m_callStack[i]), fileName, line, i - 1));
DEBUG_REPORT_LOG(true, (" (0x%016llX) %s(%d) : caller %d\n", static_cast<unsigned long long>(m_callStack[i]), fileName, line, i - 1));
else
DEBUG_REPORT_LOG(true, (" unknown(0x%08X) : caller %d\n", static_cast<int>(m_callStack[i]), i - 1));
DEBUG_REPORT_LOG(true, (" unknown(0x%016llX) : caller %d\n", static_cast<unsigned long long>(m_callStack[i]), i - 1));
}
}
@@ -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];
};
// ======================================================================
@@ -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<int>(callStackEntry->m_callStack[j]), j - 1));
REPORT_LOG(true, (" unknown(0x%016llX) : caller %d\n", static_cast<unsigned long long>(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
@@ -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<uint64>(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<uint32 *>(_alloca((callStackOffset + maxStackDepth) * sizeof(uint32)));
uint64 * callStack = static_cast<uint64 *>(_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<int>(callStack[i]), i-callStackOffset));
REPORT_LOG(true, ("\tunknown(0x%016llX) : caller %d\n", static_cast<unsigned long long>(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);
@@ -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);
};
@@ -27,10 +27,23 @@ char* _itoa(int value, char* stringOut, int radix)
bool QueryPerformanceCounter(__int64* time)
{
struct timeval tv;
gettimeofday(&tv, nullptr);
*time = static_cast<LARGE_INTEGER>(tv.tv_sec);
*time = (*time * 1000000) + static_cast<LARGE_INTEGER>(tv.tv_usec);
// Must be monotonic. gettimeofday() reports CLOCK_REALTIME, which NTP can
// slew or step backwards; callers subtract successive samples to derive
// frame time, so a backwards step produced negative elapsed times (see
// AlterScheduler "no forward time movement"). CLOCK_MONOTONIC never goes
// backwards. Units stay microseconds to match QueryPerformanceFrequency().
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
{
struct timeval tv;
gettimeofday(&tv, nullptr);
*time = static_cast<LARGE_INTEGER>(tv.tv_sec);
*time = (*time * 1000000) + static_cast<LARGE_INTEGER>(tv.tv_usec);
return TRUE;
}
*time = static_cast<LARGE_INTEGER>(ts.tv_sec);
*time = (*time * 1000000) + static_cast<LARGE_INTEGER>(ts.tv_nsec / 1000);
return TRUE;
}
@@ -32,8 +32,8 @@ namespace Archive
char temp[200];
AutoDeltaMap<NetworkId, int>::Command c;
Archive::put(target, countCharacter(buffer,':'));
Archive::put(target, static_cast<size_t>(0)); // baselineCommandCount
Archive::put(target, static_cast<int32_t>(countCharacter(buffer,':')));
Archive::put(target, static_cast<int32_t>(0)); // baselineCommandCount
int tempPos = 0;
for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i)
@@ -64,8 +64,8 @@ namespace Archive
char temp[200];
AutoDeltaMap<NetworkId, int>::Command c;
size_t commandCount;
size_t baselineCommandCount;
int32_t commandCount;
int32_t baselineCommandCount;
Archive::get(source, commandCount);
Archive::get(source, baselineCommandCount);
@@ -76,7 +76,7 @@ namespace Archive
}
else
{
for (size_t i = 0; i < commandCount; ++i)
for (int32_t i = 0; i < commandCount; ++i)
{
Archive::get(source, c.cmd);
Archive::get(source, c.key);
@@ -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<int>(Crc::calculate(format)));
else
snprintf(buffer, bufferLength, "(0x%08X) : %s %08x: \n", static_cast<int>(callStack[callStackOffset]), type, static_cast<int>(Crc::calculate(format)));
snprintf(buffer, bufferLength, "(0x%016llX) : %s %08x: \n", static_cast<unsigned long long>(callStack[callStackOffset]), type, static_cast<int>(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<int>(callStack[i]), i-callStackOffset);
snprintf(buffer, bufferLength, " (0x%016llX) : caller %d\n", static_cast<unsigned long long>(callStack[i]), i-callStackOffset);
const int length = strlen(buffer);
buffer += length;
@@ -21,8 +21,8 @@ namespace Archive
char value[200];
Command c;
Archive::put(target, countCharacter(buffer,':'));
Archive::put(target, static_cast<size_t>(0)); // baselineCommandCount
Archive::put(target, static_cast<int32_t>(countCharacter(buffer,':')));
Archive::put(target, static_cast<int32_t>(0)); // baselineCommandCount
int tempPos = 0;
for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i)
@@ -52,8 +52,8 @@ namespace Archive
char temp[200];
Command c;
size_t commandCount;
size_t baselineCommandCount;
int32_t commandCount;
int32_t baselineCommandCount;
Archive::get(source, commandCount);
Archive::get(source, baselineCommandCount);
@@ -64,7 +64,7 @@ namespace Archive
}
else
{
for (size_t i = 0; i < commandCount; ++i)
for (int32_t i = 0; i < commandCount; ++i)
{
Archive::get(source, c.cmd);
Archive::get(source, c.key);
@@ -21,8 +21,8 @@ namespace Archive
char temp[200];
Command c;
Archive::put(target, countCharacter(buffer,':'));
Archive::put(target, static_cast<size_t>(0)); // baselineCommandCount
Archive::put(target, static_cast<int32_t>(countCharacter(buffer,':')));
Archive::put(target, static_cast<int32_t>(0)); // baselineCommandCount
int tempPos = 0;
for (std::string::const_iterator i=buffer.begin(); i!=buffer.end(); ++i)
@@ -55,8 +55,8 @@ namespace Archive
char temp[200];
Command c;
size_t commandCount;
size_t baselineCommandCount;
int32_t commandCount;
int32_t baselineCommandCount;
Archive::get(source, commandCount);
Archive::get(source, baselineCommandCount);
@@ -67,7 +67,7 @@ namespace Archive
}
else
{
for (size_t i = 0; i < commandCount; ++i)
for (int32_t i = 0; i < commandCount; ++i)
{
Archive::get(source, c.cmd);
assert(c.cmd == Command::ADD); // only add is valid in unpack