mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 23:50:44 +01:00
* Core/Misc: Log more information in asserts
Add a new function GetDebugInfos() to types that could trigger an ASSERT() to easily include more useful information in crashlogs.
This is an initial commit that requires many more commits to implement the new GetDebugInfos() function in all required types.
If the type doesn't have the function, the global default one is picked which doesn't log anything.
* Core/Misc: Fix dynamic build
Add missing attribute for dynamic build
* Core/Misc: Fix gcc/clang build
* Core/Misc: Rename GetDebugInfos() to GetDebugInfo()
* Core/Misc: Fix FormatAssertionMessage() adding an extra '\0'
* Core/Misc: Add GetDebugInfo support to Unit
* Core/Misc: Add GetDebugInfo support to Creature
* Core/Misc: Add more info to GetDebugInfo for Creature
* Core/Misc: Add GetDebugInfo support to GameObject
* Core/Misc: Add GetDebugInfo support to Player
* Core/Misc: Add more GetDebugInfo info
* Core/Misc: Add GetDebugInfo support to Item
* Core/Misc: Add GetDebugInfo support to Bag
* Core/Misc: Add GetDebugInfo support to Transport
* Core/Misc: Add GetDebugInfo support to TempSummon, Minion, Guardian, Pet
* Core/Misc: Add GetDebugInfo support to Map, InstanceMap
* Core/Misc: Add GetDebugInfo support to Spell
* Core/Misc: Fix build warning
* Core/Misc: Add GetDebugInfo support to Aura
* Core/Misc: Add GetDebugInfo support to UnitAI
(cherry picked from commit 9a924fb9d5)
145 lines
4.7 KiB
C++
145 lines
4.7 KiB
C++
/*
|
|
* This file is part of the TrinityCore 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 "StringFormat.h"
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <thread>
|
|
#include <cstdarg>
|
|
|
|
/**
|
|
@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 TRINITY_PLATFORM == TRINITY_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" { TC_COMMON_API char const* TrinityAssertionFailedMessage = nullptr; }
|
|
#define Crash(message) \
|
|
TrinityAssertionFailedMessage = strdup(message); \
|
|
*((volatile int*)nullptr) = 0; \
|
|
exit(1);
|
|
#endif
|
|
|
|
namespace
|
|
{
|
|
std::string FormatAssertionMessage(char const* format, va_list args)
|
|
{
|
|
std::string formatted;
|
|
va_list len;
|
|
|
|
va_copy(len, args);
|
|
int32 length = vsnprintf(nullptr, 0, format, len);
|
|
va_end(len);
|
|
|
|
formatted.resize(length);
|
|
vsnprintf(&formatted[0], length, format, args);
|
|
|
|
return formatted;
|
|
}
|
|
}
|
|
|
|
namespace Trinity
|
|
{
|
|
|
|
void Assert(char const* file, int line, char const* function, std::string debugInfo, char const* message)
|
|
{
|
|
std::string formattedMessage = StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + debugInfo + '\n';
|
|
fprintf(stderr, "%s", formattedMessage.c_str());
|
|
fflush(stderr);
|
|
Crash(formattedMessage.c_str());
|
|
}
|
|
|
|
void Assert(char const* file, int line, char const* function, std::string debugInfo, char const* message, char const* format, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, format);
|
|
|
|
std::string formattedMessage = StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + FormatAssertionMessage(format, args) + '\n' + debugInfo + '\n';
|
|
va_end(args);
|
|
|
|
fprintf(stderr, "%s", formattedMessage.c_str());
|
|
fflush(stderr);
|
|
|
|
Crash(formattedMessage.c_str());
|
|
}
|
|
|
|
void Fatal(char const* file, int line, char const* function, char const* message, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, message);
|
|
|
|
std::string formattedMessage = StringFormat("\n%s:%i in %s FATAL ERROR:\n", file, line, function) + FormatAssertionMessage(message, args) + '\n';
|
|
va_end(args);
|
|
|
|
fprintf(stderr, "%s", formattedMessage.c_str());
|
|
fflush(stderr);
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(10));
|
|
Crash(formattedMessage.c_str());
|
|
}
|
|
|
|
void Error(char const* file, int line, char const* function, char const* message)
|
|
{
|
|
std::string formattedMessage = StringFormat("\n%s:%i in %s ERROR:\n %s\n", file, line, function, message);
|
|
fprintf(stderr, "%s", formattedMessage.c_str());
|
|
fflush(stderr);
|
|
Crash(formattedMessage.c_str());
|
|
}
|
|
|
|
void Warning(char const* file, int line, char const* function, char const* message)
|
|
{
|
|
fprintf(stderr, "\n%s:%i in %s WARNING:\n %s\n",
|
|
file, line, function, message);
|
|
}
|
|
|
|
void Abort(char const* file, int line, char const* function)
|
|
{
|
|
std::string formattedMessage = StringFormat("\n%s:%i in %s ABORTED.\n", file, line, function);
|
|
fprintf(stderr, "%s", formattedMessage.c_str());
|
|
fflush(stderr);
|
|
Crash(formattedMessage.c_str());
|
|
}
|
|
|
|
void AbortHandler(int sigval)
|
|
{
|
|
// nothing useful to log here, no way to pass args
|
|
std::string formattedMessage = StringFormat("Caught signal %i\n", sigval);
|
|
fprintf(stderr, "%s", formattedMessage.c_str());
|
|
fflush(stderr);
|
|
Crash(formattedMessage.c_str());
|
|
}
|
|
|
|
} // namespace Trinity
|
|
|
|
std::string GetDebugInfo()
|
|
{
|
|
return "";
|
|
}
|