mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-04 15:09:40 +00:00
AK: Enable backtrace() on Android API level 33 and higher
``<execinfo.h>`` was added to bionic in Android 13 (API 33)
This commit is contained in:
parent
3c39579510
commit
10d7ec2027
|
@ -7,17 +7,32 @@
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
#include <AK/Platform.h>
|
#include <AK/Platform.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
|
|
||||||
#if (defined(AK_OS_LINUX) && !defined(AK_OS_ANDROID)) || defined(AK_LIBC_GLIBC) || defined(AK_OS_BSD_GENERIC) || defined(AK_OS_SOLARIS)
|
#if (defined(AK_OS_LINUX) && !defined(AK_OS_ANDROID)) || defined(AK_LIBC_GLIBC) || defined(AK_OS_BSD_GENERIC) || defined(AK_OS_SOLARIS)
|
||||||
# define EXECINFO_BACKTRACE
|
# define EXECINFO_BACKTRACE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(AK_OS_ANDROID) && (__ANDROID_API__ >= 33)
|
||||||
|
# include <android/log.h>
|
||||||
|
# define EXECINFO_BACKTRACE
|
||||||
|
# define PRINT_ERROR(s) __android_log_write(ANDROID_LOG_WARN, "AK", (s))
|
||||||
|
#else
|
||||||
|
# define PRINT_ERROR(s) (void)fputs((s), stderr)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(EXECINFO_BACKTRACE)
|
#if defined(EXECINFO_BACKTRACE)
|
||||||
# include <cxxabi.h>
|
# include <cxxabi.h>
|
||||||
# include <execinfo.h>
|
# include <execinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(AK_OS_SERENITY)
|
||||||
|
# define ERRORLN dbgln
|
||||||
|
#else
|
||||||
|
# define ERRORLN warnln
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(KERNEL)
|
#if !defined(KERNEL)
|
||||||
|
|
||||||
# if defined(EXECINFO_BACKTRACE)
|
# if defined(EXECINFO_BACKTRACE)
|
||||||
|
@ -32,11 +47,13 @@ ALWAYS_INLINE void dump_backtrace()
|
||||||
for (auto i = 0; i < num_frames; ++i) {
|
for (auto i = 0; i < num_frames; ++i) {
|
||||||
// If there is a C++ symbol name in the line of the backtrace, demangle it
|
// If there is a C++ symbol name in the line of the backtrace, demangle it
|
||||||
StringView sym(syms[i], strlen(syms[i]));
|
StringView sym(syms[i], strlen(syms[i]));
|
||||||
|
StringBuilder error_builder;
|
||||||
if (auto idx = sym.find("_Z"sv); idx.has_value()) {
|
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
|
// 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
|
// We don't want to call dbgln() here on substring StringView because we might VERIFY() within AK::Format
|
||||||
syms[i][idx.value() - 1] = '\0';
|
syms[i][idx.value() - 1] = '\0';
|
||||||
(void)fprintf(stderr, "%s ", syms[i]);
|
error_builder.append(syms[i], strlen(syms[i]));
|
||||||
|
error_builder.append(' ');
|
||||||
|
|
||||||
auto sym_substring = sym.substring_view(idx.value());
|
auto sym_substring = sym.substring_view(idx.value());
|
||||||
auto end_of_sym = sym_substring.find_any_of("+ "sv).value_or(sym_substring.length() - 1);
|
auto end_of_sym = sym_substring.find_any_of("+ "sv).value_or(sym_substring.length() - 1);
|
||||||
|
@ -47,14 +64,21 @@ ALWAYS_INLINE void dump_backtrace()
|
||||||
auto* raw_str = &syms[i][idx.value()];
|
auto* raw_str = &syms[i][idx.value()];
|
||||||
buf = abi::__cxa_demangle(raw_str, buf, &buf_size, nullptr);
|
buf = abi::__cxa_demangle(raw_str, buf, &buf_size, nullptr);
|
||||||
|
|
||||||
(void)fputs(buf ? buf : raw_str, stderr);
|
auto* buf_to_print = buf ? buf : raw_str;
|
||||||
|
error_builder.append(buf_to_print, strlen(buf_to_print));
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
(void)fprintf(stderr, " %s", &syms[i][idx.value() + end_of_sym + 1]);
|
error_builder.append(' ');
|
||||||
|
auto* end_of_line = &syms[i][idx.value() + end_of_sym + 1];
|
||||||
|
error_builder.append(end_of_line, strlen(end_of_line));
|
||||||
} else {
|
} else {
|
||||||
(void)fputs(sym.characters_without_null_termination(), stderr);
|
error_builder.append(sym);
|
||||||
}
|
}
|
||||||
(void)fputs("\n", stderr);
|
# if !defined(AK_OS_ANDROID)
|
||||||
|
error_builder.append('\n');
|
||||||
|
# endif
|
||||||
|
error_builder.append('\0');
|
||||||
|
PRINT_ERROR(error_builder.string_view().characters_without_null_termination());
|
||||||
}
|
}
|
||||||
free(syms);
|
free(syms);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +89,7 @@ extern "C" {
|
||||||
|
|
||||||
void ak_verification_failed(char const* message)
|
void ak_verification_failed(char const* message)
|
||||||
{
|
{
|
||||||
dbgln("VERIFICATION FAILED: {}", message);
|
ERRORLN("VERIFICATION FAILED: {}", message);
|
||||||
# if defined(EXECINFO_BACKTRACE)
|
# if defined(EXECINFO_BACKTRACE)
|
||||||
dump_backtrace();
|
dump_backtrace();
|
||||||
# endif
|
# endif
|
||||||
|
|
Loading…
Reference in a new issue