Local snapshot for Docker build (includes mod-ale)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Docker Build
2026-05-06 21:18:20 -04:00
commit 72dd540b67
9823 changed files with 7356554 additions and 0 deletions
+160
View File
@@ -0,0 +1,160 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Errors.h"
#include "Duration.h"
#include <cstdio>
#include <cstdlib>
#include <thread>
/**
@file Errors.cpp
@brief This file contains definitions of functions used for reporting critical application errors
It is very important that (std::)abort is NEVER called in place of *((volatile int*)nullptr) = 0;
Calling abort() on Windows does not invoke unhandled exception filters - a mechanism used by WheatyExceptionReport
to log crashes. exit(1) calls here are for static analysis tools to indicate that calling functions defined in this file
terminates the application.
*/
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
#include <Windows.h>
#define Crash(message) \
ULONG_PTR execeptionArgs[] = { reinterpret_cast<ULONG_PTR>(strdup(message)), reinterpret_cast<ULONG_PTR>(_ReturnAddress()) }; \
RaiseException(EXCEPTION_ASSERTION_FAILURE, 0, 2, execeptionArgs);
#else
// should be easily accessible in gdb
extern "C" { char const* AcoreAssertionFailedMessage = nullptr; }
#define Crash(message) \
AcoreAssertionFailedMessage = strdup(message); \
*((volatile int*)nullptr) = 0; \
exit(1);
#endif
namespace
{
/**
* @name MakeMessage
* @brief Make message for display erros
* @param messageType Message type (ASSERTION FAILED, FATAL ERROR, ERROR) end etc
* @param file Path to file
* @param line Line number in file
* @param function Functionn name
* @param message Condition to string format
* @param fmtMessage [optional] Display format message after condition
* @param debugInfo [optional] Display debug info
*/
inline std::string MakeMessage(std::string_view messageType, std::string_view file, uint32 line, std::string_view function,
std::string_view message, std::string_view fmtMessage = {}, std::string_view debugInfo = {})
{
std::string msg = Acore::StringFormat("\n>> {}\n\n# Location: {}:{}\n# Function: {}\n# Condition: {}\n", messageType, file, line, function, message);
if (!fmtMessage.empty())
{
msg.append(Acore::StringFormat("# Message: {}\n", fmtMessage));
}
if (!debugInfo.empty())
{
msg.append(Acore::StringFormat("\n# Debug info: {}\n", debugInfo));
}
return Acore::StringFormat(
"#{0:-^{2}}#\n"
" {1: ^{2}} \n"
"#{0:-^{2}}#\n", "", msg, 70);
}
/**
* @name MakeAbortMessage
* @brief Make message for display erros
* @param file Path to file
* @param line Line number in file
* @param function Functionn name
* @param fmtMessage [optional] Display format message after condition
*/
inline std::string MakeAbortMessage(std::string_view file, uint32 line, std::string_view function, std::string_view fmtMessage = {})
{
std::string msg = Acore::StringFormat("\n>> ABORTED\n\n# Location '{}:{}'\n# Function '{}'\n", file, line, function);
if (!fmtMessage.empty())
{
msg.append(Acore::StringFormat("# Message '{}'\n", fmtMessage));
}
return Acore::StringFormat(
"\n#{0:-^{2}}#\n"
" {1: ^{2}} \n"
"#{0:-^{2}}#\n", "", msg, 70);
}
}
void Acore::Assert(std::string_view file, uint32 line, std::string_view function, std::string_view debugInfo, std::string_view message, std::string_view fmtMessage /*= {}*/)
{
std::string formattedMessage = MakeMessage("ASSERTION FAILED", file, line, function, message, fmtMessage, debugInfo);
fmt::print(stderr, "{}", formattedMessage);
fflush(stderr);
Crash(formattedMessage.c_str());
}
void Acore::Fatal(std::string_view file, uint32 line, std::string_view function, std::string_view message, std::string_view fmtMessage /*= {}*/)
{
std::string formattedMessage = MakeMessage("FATAL ERROR", file, line, function, message, fmtMessage);
fmt::print(stderr, "{}", formattedMessage);
fflush(stderr);
std::this_thread::sleep_for(10s);
Crash(formattedMessage.c_str());
}
void Acore::Error(std::string_view file, uint32 line, std::string_view function, std::string_view message)
{
std::string formattedMessage = MakeMessage("ERROR", file, line, function, message);
fmt::print(stderr, "{}", formattedMessage);
fflush(stderr);
std::this_thread::sleep_for(10s);
Crash(formattedMessage.c_str());
}
void Acore::Warning(std::string_view file, uint32 line, std::string_view function, std::string_view message)
{
std::string formattedMessage = MakeMessage("WARNING", file, line, function, message);
fmt::print(stderr, "{}", formattedMessage);
}
void Acore::Abort(std::string_view file, uint32 line, std::string_view function, std::string_view fmtMessage /*= {}*/)
{
std::string formattedMessage = MakeAbortMessage(file, line, function, fmtMessage);
fmt::print(stderr, "{}", formattedMessage);
fflush(stderr);
std::this_thread::sleep_for(10s);
Crash(formattedMessage.c_str());
}
void Acore::AbortHandler(int sigval)
{
// nothing useful to log here, no way to pass args
std::string formattedMessage = StringFormat("Caught signal {}\n", sigval);
fmt::print(stderr, "{}", formattedMessage);
fflush(stderr);
Crash(formattedMessage.c_str());
}
std::string GetDebugInfo()
{
return "";
}
+87
View File
@@ -0,0 +1,87 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ACORE_ERRORS_H_
#define _ACORE_ERRORS_H_
#include "StringFormat.h"
namespace Acore
{
// Default function
[[noreturn]] AC_COMMON_API void Assert(std::string_view file, uint32 line, std::string_view function, std::string_view debugInfo, std::string_view message, std::string_view fmtMessage = {});
[[noreturn]] AC_COMMON_API void Fatal(std::string_view file, uint32 line, std::string_view function, std::string_view message, std::string_view fmtMessage = {});
[[noreturn]] AC_COMMON_API void Error(std::string_view file, uint32 line, std::string_view function, std::string_view message);
[[noreturn]] AC_COMMON_API void Abort(std::string_view file, uint32 line, std::string_view function, std::string_view fmtMessage = {});
template<typename... Args>
AC_COMMON_API inline void Assert(std::string_view file, uint32 line, std::string_view function, std::string_view debugInfo, std::string_view message, std::string_view fmt, Args&&... args)
{
Assert(file, line, function, debugInfo, message, StringFormat(fmt, std::forward<Args>(args)...));
}
template<typename... Args>
AC_COMMON_API inline void Fatal(std::string_view file, uint32 line, std::string_view function, std::string_view message, std::string_view fmt, Args&&... args)
{
Fatal(file, line, function, message, StringFormat(fmt, std::forward<Args>(args)...));
}
template<typename... Args>
AC_COMMON_API inline void Abort(std::string_view file, uint32 line, std::string_view function, std::string_view fmt, Args&&... args)
{
Abort(file, line, function, StringFormat(fmt, std::forward<Args>(args)...));
}
AC_COMMON_API void Warning(std::string_view file, uint32 line, std::string_view function, std::string_view message);
[[noreturn]] AC_COMMON_API void AbortHandler(int sigval);
} // namespace Acore
AC_COMMON_API std::string GetDebugInfo();
#define WPAssert(cond, ...) do { if (!(cond)) Acore::Assert(__FILE__, __LINE__, __FUNCTION__, GetDebugInfo(), #cond, ##__VA_ARGS__); } while(0)
#define WPAssert_NODEBUGINFO(cond) do { if (!(cond)) Acore::Assert(__FILE__, __LINE__, __FUNCTION__, "", #cond); } while(0)
#define WPFatal(cond, ...) do { if (!(cond)) Acore::Fatal(__FILE__, __LINE__, __FUNCTION__, #cond, ##__VA_ARGS__); } while(0)
#define WPError(cond, msg) do { if (!(cond)) Acore::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0)
#define WPWarning(cond, msg) do { if (!(cond)) Acore::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0)
#define WPAbort(...) do { Acore::Abort(__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); } while(0)
#ifdef PERFORMANCE_PROFILING
#define ASSERT(cond, ...) ((void)0)
#define ASSERT_NODEBUGINFO(cond, ...) ((void)0)
#else
#define ASSERT WPAssert
#define ASSERT_NODEBUGINFO WPAssert_NODEBUGINFO
#endif
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
#define EXCEPTION_ASSERTION_FAILURE 0xC0000420L
#endif
#define ABORT WPAbort
template <typename T>
inline T* ASSERT_NOTNULL_IMPL(T* pointer, std::string_view expr)
{
ASSERT(pointer, "{}", expr);
return pointer;
}
#define ASSERT_NOTNULL(pointer) ASSERT_NOTNULL_IMPL(pointer, #pointer)
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,202 @@
#ifndef _WHEATYEXCEPTIONREPORT_
#define _WHEATYEXCEPTIONREPORT_
#if AC_PLATFORM == AC_PLATFORM_WINDOWS && !defined(__MINGW32__)
#include <dbghelp.h>
#include <mutex>
#include <set>
#include <stack>
#include <stdlib.h>
#include <winnt.h>
#include <winternl.h>
#define countof _countof
#define WER_MAX_ARRAY_ELEMENTS_COUNT 10
#define WER_MAX_NESTING_LEVEL 4
#define WER_SMALL_BUFFER_SIZE 1024
#define WER_LARGE_BUFFER_SIZE WER_SMALL_BUFFER_SIZE * 16
enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
{
btNoType = 0,
btVoid = 1,
btChar = 2,
btWChar = 3,
btInt = 6,
btUInt = 7,
btFloat = 8,
btBCD = 9,
btBool = 10,
btLong = 13,
btULong = 14,
btCurrency = 25,
btDate = 26,
btVariant = 27,
btComplex = 28,
btBit = 29,
btBSTR = 30,
btHresult = 31,
// Custom types
btStdString = 101
};
enum DataKind // Stolen from CVCONST.H in the DIA 2.0 SDK
{
DataIsUnknown,
DataIsLocal,
DataIsStaticLocal,
DataIsParam,
DataIsObjectPtr,
DataIsFileStatic,
DataIsGlobal,
DataIsMember,
DataIsStaticMember,
DataIsConstant
};
char const* const rgBaseType[] =
{
"<user defined>", // btNoType = 0,
"void", // btVoid = 1,
"char",//char* // btChar = 2,
"wchar_t*", // btWChar = 3,
"signed char",
"unsigned char",
"int", // btInt = 6,
"unsigned int", // btUInt = 7,
"float", // btFloat = 8,
"<BCD>", // btBCD = 9,
"bool", // btBool = 10,
"short",
"unsigned short",
"long", // btLong = 13,
"unsigned long", // btULong = 14,
"int8",
"int16",
"int32",
"int64",
"int128",
"uint8",
"uint16",
"uint32",
"uint64",
"uint128",
"<currency>", // btCurrency = 25,
"<date>", // btDate = 26,
"VARIANT", // btVariant = 27,
"<complex>", // btComplex = 28,
"<bit>", // btBit = 29,
"BSTR", // btBSTR = 30,
"HRESULT" // btHresult = 31
};
struct SymbolPair
{
SymbolPair(DWORD type, DWORD_PTR offset)
{
_type = type;
_offset = offset;
}
bool operator<(SymbolPair const& other) const
{
return _offset < other._offset ||
(_offset == other._offset && _type < other._type);
}
DWORD _type;
DWORD_PTR _offset;
};
typedef std::set<SymbolPair> SymbolPairs;
struct SymbolDetail
{
SymbolDetail() : Prefix(), Type(), Suffix(), Name(), Value(), Logged(false), HasChildren(false) {}
std::string ToString();
bool empty() const
{
return Value.empty() && !HasChildren;
}
std::string Prefix;
std::string Type;
std::string Suffix;
std::string Name;
std::string Value;
bool Logged;
bool HasChildren;
};
class WheatyExceptionReport
{
public:
WheatyExceptionReport();
~WheatyExceptionReport();
// entry point where control comes on an unhandled exception
static LONG WINAPI WheatyUnhandledExceptionFilter(
PEXCEPTION_POINTERS pExceptionInfo);
static void __cdecl WheatyCrtHandler(wchar_t const* expression, wchar_t const* function, wchar_t const* file, unsigned int line, uintptr_t pReserved);
static void printTracesForAllThreads(bool);
private:
// where report info is extracted and generated
static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
static void PrintSystemInfo();
static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax);
static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount);
// Helper functions
static LPTSTR GetExceptionString(DWORD dwCode);
static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len,
DWORD& section, DWORD_PTR& offset);
static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID);
static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64*);
static void DumpTypeIndex(DWORD64, DWORD, DWORD_PTR, bool&, char const*, char*, bool, bool);
static void FormatOutputValue(char* pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, std::size_t bufferSize, std::size_t countOverride = 0);
static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address);
static int __cdecl Log(const TCHAR* format, ...);
static int __cdecl StackLog(const TCHAR* format, va_list argptr);
static int __cdecl HeapLog(const TCHAR* format, va_list argptr);
static bool StoreSymbol(DWORD type, DWORD_PTR offset);
static void ClearSymbols();
// Variables used by the class
static TCHAR m_szLogFileName[MAX_PATH];
static TCHAR m_szDumpFileName[MAX_PATH];
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
static _invalid_parameter_handler m_previousCrtHandler;
static HANDLE m_hReportFile;
static HANDLE m_hDumpFile;
static HANDLE m_hProcess;
static SymbolPairs symbols;
static std::stack<SymbolDetail> symbolDetails;
static bool stackOverflowException;
static bool alreadyCrashed;
static std::mutex alreadyCrashedLock;
typedef NTSTATUS(NTAPI* pRtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation);
static pRtlGetVersion RtlGetVersion;
static void PushSymbolDetail();
static void PopSymbolDetail();
static void PrintSymbolDetail();
};
extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class
#endif // _WIN32
#endif // _WHEATYEXCEPTIONREPORT_