Legends-of-Azeroth-Pandaria-5.4.8
168 строк · 5.3 Кб
1/*
2* This file is part of the Pandaria 5.4.8 Project. See THANKS 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 <cstdio>
21#include <cstdlib>
22#include <thread>
23#include <cstdarg>
24
25/**
26@file Errors.cpp
27
28@brief This file contains definitions of functions used for reporting critical application errors
29
30It is very important that (std::)abort is NEVER called in place of *((volatile int*)NULL) = 0;
31Calling abort() on Windows does not invoke unhandled exception filters - a mechanism used by WheatyExceptionReport
32to log crashes. exit(1) calls here are for static analysis tools to indicate that calling functions defined in this file
33terminates the application.
34*/
35
36#ifdef _WIN32
37#include <Windows.h>
38#define Crash(message) \
39ULONG_PTR execeptionArgs[] = { reinterpret_cast<ULONG_PTR>(strdup(message)), reinterpret_cast<ULONG_PTR>(_ReturnAddress()) }; \
40RaiseException(EXCEPTION_ASSERTION_FAILURE, 0, 2, execeptionArgs);
41#else
42// should be easily accessible in gdb
43extern "C" { char const* TrinityAssertionFailedMessage = nullptr; }
44#define Crash(message) \
45TrinityAssertionFailedMessage = strdup(message); \
46*((volatile int*)nullptr) = 0; \
47exit(1);
48#endif
49
50namespace
51{
52std::string FormatAssertionMessage(char const* format, va_list args)
53{
54std::string formatted;
55va_list len;
56
57va_copy(len, args);
58int32 length = vsnprintf(nullptr, 0, format, len);
59va_end(len);
60
61formatted.resize(length);
62vsnprintf(&formatted[0], length + 1, format, args);
63
64return formatted;
65}
66}
67
68namespace Trinity {
69
70void Assert(char const* file, int line, char const* function, std::string debugInfo, char const* message)
71{
72std::string formattedMessage = StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + debugInfo + '\n';
73fprintf(stderr, "%s", formattedMessage.c_str());
74fflush(stderr);
75Crash(formattedMessage.c_str());
76}
77
78void Assert(char const* file, int line, char const* function, std::string debugInfo, char const* message, char const* format, ...)
79{
80va_list args;
81va_start(args, format);
82
83std::string formattedMessage = StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + FormatAssertionMessage(format, args) + '\n' + debugInfo + '\n';
84va_end(args);
85
86fprintf(stderr, "%s", formattedMessage.c_str());
87fflush(stderr);
88
89Crash(formattedMessage.c_str());
90}
91
92// void Fatal(char const* file, int line, char const* function, char const* message)
93// {
94// fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n %s\n",
95// file, line, function, message);
96// std::abort();
97// }
98
99void Fatal(char const* file, int line, char const* function, char const* message, ...)
100{
101va_list args;
102va_start(args, message);
103
104std::string formattedMessage = StringFormat("\n%s:%i in %s FATAL ERROR:\n", file, line, function) + FormatAssertionMessage(message, args) + '\n';
105va_end(args);
106
107fprintf(stderr, "%s", formattedMessage.c_str());
108fflush(stderr);
109
110std::this_thread::sleep_for(std::chrono::seconds(10));
111Crash(formattedMessage.c_str());
112}
113
114void Error(char const* file, int line, char const* function, char const* message)
115{
116fprintf(stderr, "\n%s:%i in %s ERROR:\n %s\n",
117file, line, function, message);
118std::abort();
119}
120
121void Warning(char const* file, int line, char const* function, char const* message)
122{
123fprintf(stderr, "\n%s:%i in %s WARNING:\n %s\n",
124file, line, function, message);
125}
126
127void Abort(char const* file, int line, char const* function)
128{
129std::string formattedMessage = StringFormat("\n%s:%i in %s ABORTED.\n", file, line, function);
130fprintf(stderr, "%s", formattedMessage.c_str());
131fflush(stderr);
132Crash(formattedMessage.c_str());
133}
134
135void Abort(char const* file, int line, char const* function, char const* message, ...)
136{
137va_list args;
138va_start(args, message);
139
140std::string formattedMessage = StringFormat("\n%s:%i in %s ABORTED:\n", file, line, function) + FormatAssertionMessage(message, args) + '\n';
141va_end(args);
142
143fprintf(stderr, "%s", formattedMessage.c_str());
144fflush(stderr);
145
146Crash(formattedMessage.c_str());
147}
148
149void AbortHandler(int sigval)
150{
151// nothing useful to log here, no way to pass args
152std::string formattedMessage = StringFormat("Caught signal %i\n", sigval);
153fprintf(stderr, "%s", formattedMessage.c_str());
154fflush(stderr);
155Crash(formattedMessage.c_str());
156}
157
158} // namespace Trinity
159
160void LogNotImplementedCall(char const* func)
161{
162fprintf(stderr, "Call of not implemented function: %s", func);
163}
164
165std::string GetDebugInfo()
166{
167return "";
168}