ladybird icon indicating copy to clipboard operation
ladybird copied to clipboard

AK: Add stacktrace support using the standard lib

Open R-Goc opened this issue 1 year ago • 9 comments

This commit adds support for using the standard library implementation of <stacktrace> if libbacktrace is not found.

R-Goc avatar Feb 08 '25 22:02 R-Goc

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.

R-Goc avatar Feb 08 '25 22:02 R-Goc

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.

ADKaster avatar Feb 10 '25 21:02 ADKaster

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

R-Goc avatar Feb 15 '25 00:02 R-Goc

What do you think about adding a cmake option to use the std stack trace instead of libbacktrace?

R-Goc avatar Feb 15 '25 10:02 R-Goc

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

R-Goc avatar Feb 15 '25 17:02 R-Goc

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]

ADKaster avatar Mar 04 '25 17:03 ADKaster

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?

R-Goc avatar Mar 04 '25 17:03 R-Goc

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.

ADKaster avatar Mar 04 '25 17:03 ADKaster

It's ready on my side.

R-Goc avatar Mar 04 '25 23:03 R-Goc