1
#include <c10/util/Exception.h>
2
#include <c10/util/Logging.h>
3
#include <c10/util/Type.h>
11
Error::Error(std::string msg, Backtrace backtrace, const void* caller)
12
: msg_(std::move(msg)), backtrace_(std::move(backtrace)), caller_(caller) {
16
// PyTorch-style error message
17
// Error::Error(SourceLocation source_location, const std::string& msg)
18
// NB: This is defined in Logging.cpp for access to GetFetchStackTrace
20
// Caffe2-style error message
24
const char* condition,
25
const std::string& msg,
29
str("[enforce fail at ",
30
detail::StripBasename(file),
40
std::string Error::compute_what(bool include_backtrace) const {
41
std::ostringstream oss;
45
if (context_.size() == 1) {
46
// Fold error and context in one line
47
oss << " (" << context_[0] << ")";
49
for (const auto& c : context_) {
54
if (include_backtrace && backtrace_) {
55
oss << "\n" << backtrace_->get();
61
const Backtrace& Error::backtrace() const {
65
const char* Error::what() const noexcept {
69
return compute_what(/*include_backtrace*/ true);
71
// what() is noexcept, we need to return something here.
72
return std::string{"<Error computing Error::what()>"};
78
void Error::refresh_what() {
79
// Do not compute what_ eagerly, as it would trigger the computation of the
80
// backtrace. Instead, invalidate it, it will be computed on first access.
81
// refresh_what() is only called by non-const public methods which are not
82
// supposed to be called concurrently with any other method, so it is safe to
85
what_without_backtrace_ = compute_what(/*include_backtrace*/ false);
88
void Error::add_context(std::string new_msg) {
89
context_.push_back(std::move(new_msg));
90
// TODO: Calling add_context O(n) times has O(n^2) cost. We can fix
91
// this perf problem by populating the fields lazily... if this ever
92
// actually is a problem.
93
// NB: If you do fix this, make sure you do it in a thread safe way!
94
// what() is almost certainly expected to be thread safe even when
95
// accessed across multiple threads
105
const std::string& msg) {
106
throw ::c10::Error({func, file, line}, msg);
114
throw ::c10::Error({func, file, line}, msg);
117
void torchInternalAssertFail(
122
const char* userMsg) {
123
torchCheckFail(func, file, line, c10::str(condMsg, userMsg));
126
// This should never be called. It is provided in case of compilers
127
// that don't do any dead code stripping in debug builds.
128
void torchInternalAssertFail(
133
const std::string& userMsg) {
134
torchCheckFail(func, file, line, c10::str(condMsg, userMsg));
139
namespace WarningUtils {
142
WarningHandler* getBaseHandler() {
143
static WarningHandler base_warning_handler_ = WarningHandler();
144
return &base_warning_handler_;
147
class ThreadWarningHandler {
149
ThreadWarningHandler() = delete;
151
static WarningHandler* get_handler() {
152
if (!warning_handler_) {
153
warning_handler_ = getBaseHandler();
155
return warning_handler_;
158
static void set_handler(WarningHandler* handler) {
159
warning_handler_ = handler;
163
static thread_local WarningHandler* warning_handler_;
166
thread_local WarningHandler* ThreadWarningHandler::warning_handler_ = nullptr;
170
void set_warning_handler(WarningHandler* handler) noexcept(true) {
171
ThreadWarningHandler::set_handler(handler);
174
WarningHandler* get_warning_handler() noexcept(true) {
175
return ThreadWarningHandler::get_handler();
178
bool warn_always = false;
180
void set_warnAlways(bool setting) noexcept(true) {
181
warn_always = setting;
184
bool get_warnAlways() noexcept(true) {
188
WarnAlways::WarnAlways(bool setting /*=true*/)
189
: prev_setting(get_warnAlways()) {
190
set_warnAlways(setting);
193
WarnAlways::~WarnAlways() {
194
set_warnAlways(prev_setting);
197
} // namespace WarningUtils
199
void warn(const Warning& warning) {
200
WarningUtils::ThreadWarningHandler::get_handler()->process(warning);
204
warning_variant_t type,
205
const SourceLocation& source_location,
209
source_location_(source_location),
210
msg_(std::move(msg)),
211
verbatim_(verbatim) {}
214
warning_variant_t type,
215
SourceLocation source_location,
216
detail::CompileTimeEmptyString msg,
218
: Warning(type, source_location, "", verbatim) {}
221
warning_variant_t type,
222
SourceLocation source_location,
226
source_location_(source_location),
227
msg_(std::string(msg)),
228
verbatim_(verbatim) {}
230
Warning::warning_variant_t Warning::type() const {
234
const SourceLocation& Warning::source_location() const {
235
return source_location_;
238
const std::string& Warning::msg() const {
242
bool Warning::verbatim() const {
246
void WarningHandler::process(const Warning& warning) {
248
WARNING, warning.source_location().file, warning.source_location().line)
249
<< "Warning: " << warning.msg() << " (function "
250
<< warning.source_location().function << ")";
253
std::string GetExceptionString(const std::exception& e) {
255
return demangle(typeid(e).name()) + ": " + e.what();
257
return std::string("Exception (no RTTI available): ") + e.what();