TrinityCore
Loading...
Searching...
No Matches
Errors.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Errors.h"
19#include "StringFormat.h"
20#include <thread>
21#include <cstdarg>
22#include <cstdio>
23#include <cstring>
24
36#if TRINITY_COMPILER_IS_MICROSOFT
37#define Unreachable() __assume(false)
38#define GetReturnAddress() _ReturnAddress()
39#else
40#define Unreachable() __builtin_unreachable()
41#define GetReturnAddress() __builtin_return_address(0)
42#endif
43
44#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
45#include <Windows.h>
46#include <intrin.h>
47#define Crash(message) \
48 ULONG_PTR execeptionArgs[] = { reinterpret_cast<ULONG_PTR>(strdup(message)), reinterpret_cast<ULONG_PTR>(GetReturnAddress()) }; \
49 RaiseException(EXCEPTION_ASSERTION_FAILURE, 0, 2, execeptionArgs); \
50 Unreachable()
51#else
52// should be easily accessible in gdb
53extern "C" { TC_COMMON_API char const* TrinityAssertionFailedMessage = nullptr; }
54#define Crash(message) \
55 TrinityAssertionFailedMessage = strdup(message); \
56 *((volatile int*)nullptr) = 0; \
57 Unreachable()
58#endif
59
60namespace
61{
62 void FormatAssertionMessageTo(std::string& formatted, char const* format, va_list args) noexcept
63 {
64 va_list len;
65
66 va_copy(len, args);
67 int32 length = vsnprintf(nullptr, 0, format, len);
68 va_end(len);
69
70 std::size_t offset = formatted.length();
71 formatted.resize(offset + length);
72 vsnprintf(&formatted[offset], length + 1, format, args);
73 }
74}
75
76namespace Trinity
77{
78void Assert(char const* file, int line, char const* function, char const* message, std::string debugInfo) noexcept
79{
80 std::string formattedMessage = StringFormat("\n{}:{} in {} ASSERTION FAILED:\n {}\n{}\n", file, line, function, message, debugInfo);
81 fprintf(stderr, "%s", formattedMessage.c_str());
82 fflush(stderr);
83 Crash(formattedMessage.c_str());
84}
85
86void Assert(char const* file, int line, char const* function, char const* message, std::string debugInfo, char const* format, ...) noexcept
87{
88 va_list args;
89 va_start(args, format);
90
91 std::string formattedMessage = StringFormat("\n{}:{} in {} ASSERTION FAILED:\n {}\n", file, line, function, message);
92 FormatAssertionMessageTo(formattedMessage, format, args);
93 va_end(args);
94
95 formattedMessage.append(1, '\n');
96 formattedMessage.append(debugInfo);
97 formattedMessage.append(1, '\n');
98
99 fprintf(stderr, "%s", formattedMessage.c_str());
100 fflush(stderr);
101
102 Crash(formattedMessage.c_str());
103}
104
105void Fatal(char const* file, int line, char const* function, char const* message, ...) noexcept
106{
107 va_list args;
108 va_start(args, message);
109
110 std::string formattedMessage = StringFormat("\n{}:{} in {} FATAL ERROR:\n", file, line, function);
111 FormatAssertionMessageTo(formattedMessage, message, args);
112 va_end(args);
113
114 formattedMessage.append(1, '\n');
115
116 fprintf(stderr, "%s", formattedMessage.c_str());
117 fflush(stderr);
118
119 std::this_thread::sleep_for(std::chrono::seconds(10));
120 Crash(formattedMessage.c_str());
121}
122
123void Error(char const* file, int line, char const* function, char const* message) noexcept
124{
125 std::string formattedMessage = StringFormat("\n{}:{} in {} ERROR:\n {}\n", file, line, function, message);
126 fprintf(stderr, "%s", formattedMessage.c_str());
127 fflush(stderr);
128 Crash(formattedMessage.c_str());
129}
130
131void Warning(char const* file, int line, char const* function, char const* message) noexcept
132{
133 fprintf(stderr, "\n%s:%i in %s WARNING:\n %s\n",
134 file, line, function, message);
135}
136
137void Abort(char const* file, int line, char const* function) noexcept
138{
139 std::string formattedMessage = StringFormat("\n{}:{} in {} ABORTED.\n", file, line, function);
140 fprintf(stderr, "%s", formattedMessage.c_str());
141 fflush(stderr);
142 Crash(formattedMessage.c_str());
143}
144
145void Abort(char const* file, int line, char const* function, char const* message, ...) noexcept
146{
147 va_list args;
148 va_start(args, message);
149
150 std::string formattedMessage = StringFormat("\n{}:{} in {} ABORTED:\n", file, line, function);
151 FormatAssertionMessageTo(formattedMessage, message, args);
152 va_end(args);
153
154 formattedMessage.append(1, '\n');
155
156 fprintf(stderr, "%s", formattedMessage.c_str());
157 fflush(stderr);
158
159 Crash(formattedMessage.c_str());
160}
161
162void AbortHandler(int sigval) noexcept
163{
164 // nothing useful to log here, no way to pass args
165 std::string formattedMessage = StringFormat("Caught signal {}\n", sigval);
166 fprintf(stderr, "%s", formattedMessage.c_str());
167 fflush(stderr);
168 Crash(formattedMessage.c_str());
169}
170} // namespace Trinity
171
172std::string GetDebugInfo()
173{
174 return "";
175}
#define TC_COMMON_API
Definition Define.h:99
int32_t int32
Definition Define.h:150
std::string GetDebugInfo()
Definition Errors.cpp:172
#define Crash(message)
Definition Errors.cpp:47
void Assert(char const *file, int line, char const *function, char const *message, std::string debugInfo) noexcept
Definition Errors.cpp:78
void Error(char const *file, int line, char const *function, char const *message) noexcept
Definition Errors.cpp:123
std::string StringFormat(FormatString< Args... > fmt, Args &&... args) noexcept
Default TC string format function.
void Abort(char const *file, int line, char const *function) noexcept
Definition Errors.cpp:137
void Fatal(char const *file, int line, char const *function, char const *message,...) noexcept
Definition Errors.cpp:105
void AbortHandler(int sigval) noexcept
Definition Errors.cpp:162