AK: Add stacktrace support using the standard lib
This commit adds support for using the standard library implementation of <stacktrace> if libbacktrace is not found.
Not sure if I should be linking the GCC specific libs in cmake or inside a pragma comment lib. The current release notes for gcc 15 don't mention adding stacktrace as stable.
Not sure if I should be linking the GCC specific libs in cmake or inside a pragma comment lib.
Pragma comment lib is an MSVC-ism. I would be shocked if GCC supported it, and weirded out if I saw it in a cpp file compiled on ELF platforms.
I don't know if there is any way to check all these. Also not completely sure about the branches in the cmake, but should be fine. Edit: clearly it's wrong Edit 2: I would've thought a always true conditional directive would cause a warning
What do you think about adding a cmake option to use the std stack trace instead of libbacktrace?
This seems reasonable to me. Replacing this bespoke "print backtrace" impl that doesn't print quite enough information with a std version that might go the extra mile seems reasonable for when all our platforms support it.
In the meantime, adding support for non-backtrace(3) platforms through the STL seems like a fine way to avoid learning platform specifics we don't really care about.
Realistically all but libcxx support it, and someone is working to get it there as well, but that doesn't seem close to the end of work yet. Maybe it would be in time for the 21 release. As a matter of fact Clang using libstdc++ should be the same, I guess my cmake doesn't support this. Though on godbolt clang earlier than 19 fails with a weird error: https://godbolt.org/z/c5nsvr3W9
This should work on all our platforms now. I moved things around to make sure we actually use std::stacktrace when requested.
That being said, libstdc++'s implementation is uh. well it makes some interesting choices.
backtrace_symbols(3) vs std::stacktrace::current()
stacktrace:
VERIFICATION FAILED: !is_error() at /home/andrew/ladybird-org/ladybird-browser/AK/Error.h:183
0# dump_backtrace at /home/andrew/ladybird-org/ladybird-browser/AK/Assertions.cpp:41
1# ak_verification_failed at /home/andrew/ladybird-org/ladybird-browser/AK/Assertions.cpp:123
2# initialize_client at /home/andrew/ladybird-org/ladybird-browser/Libraries/LibWebView/ViewImplementation.cpp:0
3# initialize_client at /home/andrew/ladybird-org/ladybird-browser/UI/Qt/WebContentView.cpp:628
4# Tab at /home/andrew/ladybird-org/ladybird-browser/UI/Qt/Tab.cpp:58
5# create_new_tab at /home/andrew/ladybird-org/ladybird-browser/UI/Qt/BrowserWindow.cpp:757
6# new_tab_from_url at /home/andrew/ladybird-org/ladybird-browser/UI/Qt/BrowserWindow.cpp:718
7# at :0
8# QAction::triggered(bool) at :0
9# QAction::activate(QAction::ActionEvent) at :0
10# at :0
11# QAbstractButton::mouseReleaseEvent(QMouseEvent*) at :0
12# QToolButton::mouseReleaseEvent(QMouseEvent*) at :0
13# QWidget::event(QEvent*) at :0
14# QApplicationPrivate::notify_helper(QObject*, QEvent*) at :0
15# QApplication::notify(QObject*, QEvent*) at :0
16# QCoreApplication::notifyInternal2(QObject*, QEvent*) at :0
17# QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) at :0
18# at :0
19# at :0
20# QApplicationPrivate::notify_helper(QObject*, QEvent*) at :0
21# QCoreApplication::notifyInternal2(QObject*, QEvent*) at :0
22# QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) at :0
23# QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) at :0
24# at :0
25# at :0
26# at :0
27# g_main_context_iteration at :0
28# QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) at :0
29# QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) at :0
30# QCoreApplication::exec() at :0
31# exec at /home/andrew/ladybird-org/ladybird-browser/Libraries/LibCore/EventLoop.cpp:83
32# WebView::Application::execute() at /home/andrew/ladybird-org/ladybird-browser/Libraries/LibWebView/Application.cpp:246
33# serenity_main at /home/andrew/ladybird-org/ladybird-browser/UI/Qt/main.cpp:144
34# main at /home/andrew/ladybird-org/ladybird-browser/Libraries/LibMain/Main.cpp:39
35# __libc_start_call_main at ../sysdeps/nptl/libc_start_call_main.h:58
36# __libc_start_main_impl at ../csu/libc-start.c:360
37# _start at :0
38#
backtrace_symbols:
VERIFICATION FAILED: !is_error() at /home/andrew/ladybird-org/ladybird-browser/AK/Error.h:183
/home/andrew/ladybird-org/ladybird-browser/Build/release/lib/liblagom-ak.so.0(ak_trap+0x35) [0x77a4cee5e1e5]
/home/andrew/ladybird-org/ladybird-browser/Build/release/lib/liblagom-ak.so.0(+0x2b4ff) [0x77a4cee5e4ff]
/home/andrew/ladybird-org/ladybird-browser/Build/release/lib/liblagom-webview.so.0 WebView::ViewImplementation::initialize_client(WebView::ViewImplementation::CreateNewClient) 0x74c) [0x77a4d322eb2c]
/home/andrew/ladybird-org/ladybird-browser/Build/release/bin/Ladybird(+0x6d28a) [0x56fbe695028a]
/home/andrew/ladybird-org/ladybird-browser/Build/release/bin/Ladybird(+0x5dd46) [0x56fbe6940d46]
/home/andrew/ladybird-org/ladybird-browser/Build/release/bin/Ladybird(+0x4bd85) [0x56fbe692ed85]
/home/andrew/ladybird-org/ladybird-browser/Build/release/bin/Ladybird(+0x50986) [0x56fbe6933986]
/lib/x86_64-linux-gnu/libQt6Core.so.6(+0x183d9b) [0x77a4d1583d9b]
/lib/x86_64-linux-gnu/libQt6Gui.so.6 QAction::triggered(bool) 0x44) [0x77a4d1e54f44]
/lib/x86_64-linux-gnu/libQt6Gui.so.6 QAction::activate(QAction::ActionEvent) 0x129) [0x77a4d1e5a299]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6(+0x28ed42) [0x77a4d248ed42]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6 QAbstractButton::mouseReleaseEvent(QMouseEvent*) 0xc3) [0x77a4d249c013]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6 QToolButton::mouseReleaseEvent(QMouseEvent*) 0x16) [0x77a4d259d106]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6 QWidget::event(QEvent*) 0x89f) [0x77a4d23d484f]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6 QApplicationPrivate::notify_helper(QObject*, QEvent*) 0x90) [0x77a4d238b3b0]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6 QApplication::notify(QObject*, QEvent*) 0xef7) [0x77a4d23842c7]
/lib/x86_64-linux-gnu/libQt6Core.so.6 QCoreApplication::notifyInternal2(QObject*, QEvent*) 0x128) [0x77a4d1538448]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6 QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) 0x38e) [0x77a4d2380d7e]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6(+0x1e2ad7) [0x77a4d23e2ad7]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6(+0x1e3e75) [0x77a4d23e3e75]
/lib/x86_64-linux-gnu/libQt6Widgets.so.6 QApplicationPrivate::notify_helper(QObject*, QEvent*) 0x90) [0x77a4d238b3b0]
/lib/x86_64-linux-gnu/libQt6Core.so.6 QCoreApplication::notifyInternal2(QObject*, QEvent*) 0x128) [0x77a4d1538448]
/lib/x86_64-linux-gnu/libQt6Gui.so.6 QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) 0x897) [0x77a4d1b96de7]
/lib/x86_64-linux-gnu/libQt6Gui.so.6 QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) 0xac) [0x77a4d1be15cc]
/lib/x86_64-linux-gnu/libQt6Gui.so.6(+0x5152b4) [0x77a4d1f152b4]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x5d5b5) [0x77a4ce2535b5]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(+0xbc717) [0x77a4ce2b2717]
/lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_iteration+0x33) [0x77a4ce252a53]
/lib/x86_64-linux-gnu/libQt6Core.so.6 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) 0x6f) [0x77a4d17315ef]
/lib/x86_64-linux-gnu/libQt6Core.so.6 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) 0x2e3) [0x77a4d15429a3]
/lib/x86_64-linux-gnu/libQt6Core.so.6 QCoreApplication::exec() 0x9e) [0x77a4d153b35e]
/home/andrew/ladybird-org/ladybird-browser/Build/release/lib/liblagom-core.so.0 Core::EventLoop::exec() 0x37) [0x77a4cf5d5097]
/home/andrew/ladybird-org/ladybird-browser/Build/release/lib/liblagom-webview.so.0 WebView::Application::execute() 0x10) [0x77a4d31f0830]
/home/andrew/ladybird-org/ladybird-browser/Build/release/bin/Ladybird(+0x742f0) [0x56fbe69572f0]
/home/andrew/ladybird-org/ladybird-browser/Build/release/bin/Ladybird(+0x74b7f) [0x56fbe6957b7f]
/lib/x86_64-linux-gnu/libc.so.6(+0x2a1ca) [0x77a4ce62a1ca]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x8b) [0x77a4ce62a28b]
/home/andrew/ladybird-org/ladybird-browser/Build/release/bin/Ladybird(+0x3cd55) [0x56fbe691fd55]
I was actually wondering about that. I though it was some WSL weirdness, but appears not. Looking at this we might want to change this backtrace to not include the last two frames(as in the two inside assertions.cpp). What do you think?
Looking at this we might want to change this backtrace to not include the last two frames(as in the two inside assertions.cpp). What do you think?
Meh on that one. Doesn't hurt much. I'd be more interested to see if we can convince the compiler to inline the dump function in a way that it doesn't show up in the backtrace. Having ak_assertion_failed in there makes sense.
It's ready on my side.