From cbfb8b16e66a3b35b08c38914af9682fc4509bb3 Mon Sep 17 00:00:00 2001 From: Junru Shao Date: Mon, 26 Jun 2023 22:03:34 -0700 Subject: [PATCH] [Runtime] Clean TVM stacktrace in error messages This PR introduces some cleanups on the stacktraces in TVM's error message by removing the meaningless frames, for example, C++ template dispatch with `std::enable_if`. --- include/tvm/runtime/logging.h | 28 +++++++--------------------- python/tvm/error.py | 8 +------- src/runtime/logging.cc | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/include/tvm/runtime/logging.h b/include/tvm/runtime/logging.h index b742d59520155..06a1ef964d0e0 100644 --- a/include/tvm/runtime/logging.h +++ b/include/tvm/runtime/logging.h @@ -367,11 +367,7 @@ class LogFatal { this->lineno_ = lineno; } [[noreturn]] TVM_NO_INLINE dmlc::Error Finalize() { - InternalError error(file_, lineno_, stream_.str()); -#if DMLC_LOG_BEFORE_THROW - std::cerr << error.what() << std::endl; -#endif - throw error; + throw InternalError(file_, lineno_, stream_.str()); } std::ostringstream stream_; std::string file_; @@ -539,13 +535,6 @@ class VLogContextEntry { std::stringstream sstream_; }; -constexpr const char* kTVM_INTERNAL_ERROR_MESSAGE = - "\n" - "---------------------------------------------------------------\n" - "An error occurred during the execution of TVM.\n" - "For more information, please see: https://tvm.apache.org/docs/errors.html\n" - "---------------------------------------------------------------\n"; - template std::unique_ptr LogCheckFormat(const X& x, const Y& y) { std::ostringstream os; @@ -694,14 +683,12 @@ TVM_CHECK_FUNC(_NE, !=) #define ICHECK_BINARY_OP(name, op, x, y) \ if (auto __tvm__log__err = ::tvm::runtime::detail::LogCheck##name(x, y)) \ ::tvm::runtime::detail::LogFatal(__FILE__, __LINE__).stream() \ - << ::tvm::runtime::detail::kTVM_INTERNAL_ERROR_MESSAGE << std::endl \ - << TVM_ICHECK_INDENT << "Check failed: " << #x " " #op " " #y << *__tvm__log__err << ": " + << "InternalError: Check failed: " << #x " " #op " " #y << *__tvm__log__err << ": " -#define ICHECK(x) \ - if (!(x)) \ - ::tvm::runtime::detail::LogFatal(__FILE__, __LINE__).stream() \ - << ::tvm::runtime::detail::kTVM_INTERNAL_ERROR_MESSAGE << TVM_ICHECK_INDENT \ - << "Check failed: (" #x << ") is false: " +#define ICHECK(x) \ + if (!(x)) \ + ::tvm::runtime::detail::LogFatal(__FILE__, __LINE__).stream() \ + << "InternalError: Check failed: (" #x << ") is false: " #define ICHECK_LT(x, y) ICHECK_BINARY_OP(_LT, <, x, y) #define ICHECK_GT(x, y) ICHECK_BINARY_OP(_GT, >, x, y) @@ -711,8 +698,7 @@ TVM_CHECK_FUNC(_NE, !=) #define ICHECK_NE(x, y) ICHECK_BINARY_OP(_NE, !=, x, y) #define ICHECK_NOTNULL(x) \ ((x) == nullptr ? ::tvm::runtime::detail::LogFatal(__FILE__, __LINE__).stream() \ - << ::tvm::runtime::detail::kTVM_INTERNAL_ERROR_MESSAGE \ - << TVM_ICHECK_INDENT << "Check not null: " #x << ' ', \ + << "InternalError: Check not null: " #x << ' ', \ (x) : (x)) // NOLINT(*) } // namespace runtime diff --git a/python/tvm/error.py b/python/tvm/error.py index f3f8b71f1a523..afd079ca6ba8f 100644 --- a/python/tvm/error.py +++ b/python/tvm/error.py @@ -25,7 +25,7 @@ Please also refer to :ref:`error-handling-guide`. """ -from tvm._ffi.base import register_error, TVMError +from tvm._ffi.base import TVMError, register_error @register_error @@ -46,12 +46,6 @@ class InternalError(TVMError): """ def __init__(self, msg): - # Patch up additional hint message. - if "TVM hint:" not in msg: - msg += ( - "\nTVM hint: You hit an internal error. " - + "Please open a thread on https://discuss.tvm.apache.org/ to report it." - ) super(InternalError, self).__init__(msg) diff --git a/src/runtime/logging.cc b/src/runtime/logging.cc index 0569a78a0fcd6..5e7431e5109c6 100644 --- a/src/runtime/logging.cc +++ b/src/runtime/logging.cc @@ -18,6 +18,8 @@ */ #include +#include +#include #include #include @@ -92,6 +94,31 @@ void BacktraceSyminfoCallback(void* data, uintptr_t pc, const char* symname, uin int BacktraceFullCallback(void* data, uintptr_t pc, const char* filename, int lineno, const char* symbol) { + if (filename != nullptr) { + if (strstr(filename, "include/tvm/runtime/packed_func.h") != nullptr || + strstr(filename, "include/tvm/runtime/registry.h") != nullptr || + strstr(filename, "include/tvm/node/functor.h") != nullptr || + strstr(filename, "include/tvm/relax/expr_functor.h") != nullptr || + strstr(filename, "include/tvm/tir/stmt_functor.h") != nullptr || + strstr(filename, "include/tvm/tir/expr_functor.h") != nullptr || + strstr(filename, "include/tvm/node/reflection.h") != nullptr || + strstr(filename, "src/node/structural_equal.cc") != nullptr || + strstr(filename, "src/ir/transform.cc") != nullptr || + strstr(filename, "src/tir/ir/stmt_functor.cc") != nullptr || + strstr(filename, "src/tir/ir/expr_functor.cc") != nullptr || + strstr(filename, "src/relax/ir/expr_functor.cc") != nullptr || + strstr(filename, "src/relax/ir/py_expr_functor.cc") != nullptr || + strstr(filename, "src/runtime/c_runtime_api.cc") != nullptr || + strstr(filename, "/python-") != nullptr || // + strstr(filename, "include/c++/") != nullptr) { + return 0; + } + } + if (symbol != nullptr) { + if (strstr(symbol, "__libc_") != nullptr) { + return 0; + } + } auto stack_trace = reinterpret_cast(data); std::stringstream s; @@ -170,9 +197,11 @@ std::string Backtrace() { return ""; } // libbacktrace eats memory if run on multiple threads at the same time, so we guard against it - static std::mutex m; - std::lock_guard lock(m); - backtrace_full(_bt_state, 0, BacktraceFullCallback, BacktraceErrorCallback, &bt); + { + static std::mutex m; + std::lock_guard lock(m); + backtrace_full(_bt_state, 0, BacktraceFullCallback, BacktraceErrorCallback, &bt); + } std::ostringstream s; s << "Stack trace:\n";