mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-11 08:50:37 +00:00
AK: Always use our assertion failure method, and add backtrace to it
On platforms that support it, enable using ``<execinfo.h>`` to get backtrace(3) to dump a backtrace on assertion failure. This should make debugging things like WebContent crashes in Lagom much easier.
This commit is contained in:
parent
3056ff6b11
commit
4641af7873
Notes:
sideshowbarker
2024-07-16 22:14:49 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/4641af7873 Pull-request: https://github.com/SerenityOS/serenity/pull/20852
3 changed files with 65 additions and 10 deletions
|
@ -6,13 +6,68 @@
|
|||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Format.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StringView.h>
|
||||
|
||||
#if defined(AK_OS_LINUX) || defined(AK_OS_BSD_GENERIC) || defined(AK_OS_SOLARIS)
|
||||
# define EXECINFO_BACKTRACE
|
||||
#endif
|
||||
|
||||
#if defined(EXECINFO_BACKTRACE)
|
||||
# include <cxxabi.h>
|
||||
# include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#if !defined(KERNEL)
|
||||
|
||||
# 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]);
|
||||
|
||||
auto end_of_sym = sym.find(' ', idx.value()).value_or(sym.length() - 1);
|
||||
syms[i][end_of_sym] = '\0';
|
||||
|
||||
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);
|
||||
|
||||
(void)fprintf(stderr, " %s", &syms[i][end_of_sym + 1]);
|
||||
} else {
|
||||
(void)fputs(sym.characters_without_null_termination(), stderr);
|
||||
}
|
||||
(void)fputs("\n", stderr);
|
||||
}
|
||||
free(syms);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
void ak_verification_failed(char const* message)
|
||||
{
|
||||
dbgln("VERIFICATION FAILED: {}", message);
|
||||
# if defined(EXECINFO_BACKTRACE)
|
||||
dump_backtrace();
|
||||
# endif
|
||||
__builtin_trap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,16 +11,12 @@
|
|||
#else
|
||||
# include <assert.h>
|
||||
extern "C" __attribute__((noreturn)) void ak_verification_failed(char const*);
|
||||
# if !defined(NDEBUG) && !defined(WIN32)
|
||||
# define VERIFY assert
|
||||
# else
|
||||
# define __stringify_helper(x) #x
|
||||
# define __stringify(x) __stringify_helper(x)
|
||||
# define VERIFY(expr) \
|
||||
(__builtin_expect(!(expr), 0) \
|
||||
? ak_verification_failed(#expr "\n" __FILE__ ":" __stringify(__LINE__)) \
|
||||
: (void)0)
|
||||
# endif
|
||||
# define __stringify_helper(x) #x
|
||||
# define __stringify(x) __stringify_helper(x)
|
||||
# define VERIFY(expr) \
|
||||
(__builtin_expect(!(expr), 0) \
|
||||
? ak_verification_failed(#expr " at " __FILE__ ":" __stringify(__LINE__)) \
|
||||
: (void)0)
|
||||
# define VERIFY_NOT_REACHED() VERIFY(false) /* NOLINT(cert-dcl03-c,misc-static-assert) No, this can't be static_assert, it's a runtime check */
|
||||
static constexpr bool TODO = false;
|
||||
# define TODO() VERIFY(TODO) /* NOLINT(cert-dcl03-c,misc-static-assert) No, this can't be static_assert, it's a runtime check */
|
||||
|
|
|
@ -331,6 +331,10 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
|||
# Solaris has socket and networking related functions in two extra libraries
|
||||
target_link_libraries(LibCore PRIVATE nsl socket)
|
||||
endif()
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "BSD$")
|
||||
# BSD Platforms have backtrace(3) in a separate library
|
||||
target_link_libraries(LibCore PRIVATE execinfo)
|
||||
endif()
|
||||
target_sources(LibCore PRIVATE ${AK_SOURCES})
|
||||
|
||||
# LibMain
|
||||
|
|
Loading…
Reference in a new issue