Skip to content

Commit

Permalink
[Runtime] Clean TVM stacktrace in error messages (#15161)
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
junrushao committed Jun 27, 2023
1 parent 5e77b7e commit b9c76f5
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
22 changes: 6 additions & 16 deletions include/tvm/runtime/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -539,13 +539,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 <typename X, typename Y>
std::unique_ptr<std::string> LogCheckFormat(const X& x, const Y& y) {
std::ostringstream os;
Expand Down Expand Up @@ -694,14 +687,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)
Expand All @@ -711,8 +702,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
Expand Down
8 changes: 1 addition & 7 deletions python/tvm/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)


Expand Down
35 changes: 32 additions & 3 deletions src/runtime/logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
#include <tvm/runtime/logging.h>

#include <cstdio>
#include <cstring>
#include <stdexcept>
#include <string>

Expand Down Expand Up @@ -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<BacktraceInfo*>(data);
std::stringstream s;

Expand Down Expand Up @@ -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<std::mutex> lock(m);
backtrace_full(_bt_state, 0, BacktraceFullCallback, BacktraceErrorCallback, &bt);
{
static std::mutex m;
std::lock_guard<std::mutex> lock(m);
backtrace_full(_bt_state, 0, BacktraceFullCallback, BacktraceErrorCallback, &bt);
}

std::ostringstream s;
s << "Stack trace:\n";
Expand Down

0 comments on commit b9c76f5

Please sign in to comment.