2022-10-06 11:35:46 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <AK/Assertions.h>
|
|
|
|
#include <AK/Format.h>
|
2023-08-30 14:54:33 +00:00
|
|
|
#include <AK/Platform.h>
|
|
|
|
#include <AK/StringView.h>
|
|
|
|
|
2023-09-02 15:11:35 +00:00
|
|
|
#if (defined(AK_OS_LINUX) && !defined(AK_OS_ANDROID)) || defined(AK_OS_BSD_GENERIC) || defined(AK_OS_SOLARIS)
|
2023-08-30 14:54:33 +00:00
|
|
|
# define EXECINFO_BACKTRACE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(EXECINFO_BACKTRACE)
|
|
|
|
# include <cxxabi.h>
|
|
|
|
# include <execinfo.h>
|
|
|
|
#endif
|
2022-10-06 11:35:46 +00:00
|
|
|
|
2023-02-05 15:15:55 +00:00
|
|
|
#if !defined(KERNEL)
|
2023-08-30 14:54:33 +00:00
|
|
|
|
|
|
|
# if defined(EXECINFO_BACKTRACE)
|
|
|
|
namespace {
|
|
|
|
ALWAYS_INLINE void dump_backtrace()
|
|
|
|
{
|
|
|
|
// Grab symbols and dso name for up to 256 frames
|
|
|
|
void* trace[256] = {};
|
|
|
|
int const num_frames = backtrace(trace, sizeof(trace));
|
|
|
|
char** syms = backtrace_symbols(trace, num_frames);
|
|
|
|
|
|
|
|
for (auto i = 0; i < num_frames; ++i) {
|
|
|
|
// If there is a C++ symbol name in the line of the backtrace, demangle it
|
|
|
|
StringView sym(syms[i], strlen(syms[i]));
|
|
|
|
if (auto idx = sym.find("_Z"sv); idx.has_value()) {
|
|
|
|
// Play C games with the original string so we can print before and after the mangled symbol with a C API
|
|
|
|
// We don't want to call dbgln() here on substring StringView because we might VERIFY() within AK::Format
|
|
|
|
syms[i][idx.value() - 1] = '\0';
|
|
|
|
(void)fprintf(stderr, "%s ", syms[i]);
|
|
|
|
|
2023-09-02 19:07:45 +00:00
|
|
|
auto sym_substring = sym.substring_view(idx.value());
|
|
|
|
auto end_of_sym = sym_substring.find_any_of("+ "sv).value_or(sym_substring.length() - 1);
|
|
|
|
syms[i][idx.value() + end_of_sym] = '\0';
|
2023-08-30 14:54:33 +00:00
|
|
|
|
|
|
|
size_t buf_size = 128u;
|
|
|
|
char* buf = static_cast<char*>(malloc(buf_size));
|
|
|
|
auto* raw_str = &syms[i][idx.value()];
|
|
|
|
buf = abi::__cxa_demangle(raw_str, buf, &buf_size, nullptr);
|
|
|
|
|
|
|
|
(void)fputs(buf ? buf : raw_str, stderr);
|
|
|
|
free(buf);
|
|
|
|
|
2023-09-02 19:07:45 +00:00
|
|
|
(void)fprintf(stderr, " %s", &syms[i][idx.value() + end_of_sym + 1]);
|
2023-08-30 14:54:33 +00:00
|
|
|
} else {
|
|
|
|
(void)fputs(sym.characters_without_null_termination(), stderr);
|
|
|
|
}
|
|
|
|
(void)fputs("\n", stderr);
|
|
|
|
}
|
|
|
|
free(syms);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
2022-10-06 11:35:46 +00:00
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
void ak_verification_failed(char const* message)
|
|
|
|
{
|
|
|
|
dbgln("VERIFICATION FAILED: {}", message);
|
2023-08-30 14:54:33 +00:00
|
|
|
# if defined(EXECINFO_BACKTRACE)
|
|
|
|
dump_backtrace();
|
|
|
|
# endif
|
2022-10-06 11:35:46 +00:00
|
|
|
__builtin_trap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|